a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 系統(tǒng) > Android > 正文

Android后臺線程和UI線程通訊實例

2020-04-11 11:49:33
字體:
來源:轉載
供稿:網(wǎng)友

本節(jié)向你展示如何在任務中發(fā)送數(shù)據(jù)給UI線程里的對象,這個特性允許你在后臺線程工作,完了在UI線程展示結果。

在UI線程定義一個Handler

Handler是Android系統(tǒng)線程管理框架里的一部分。一個Handler對象接收消息,并且運行代碼來處理消息。正常情況下,你為新線程創(chuàng)建Handler,但你也可以為已有的線程創(chuàng)建一個Handler.當你連接Handler到UI線程時,處理消息的代碼會在UI線程上運行.

在創(chuàng)建線程池的類的構造器里實例化Handler對象,保存在全局變量里。用Handler(Looper)方法實例化,連接到UI線程,構造方法使用Looper對象,也是Android系統(tǒng)線程管理框架里的一部分.Looper類有一個靜態(tài)方法getMainLooper()可以獲取UI線程的Looper對象。如:

復制代碼 代碼如下:

private PhotoManager() {
...
    // Defines a Handler object that's attached to the UI thread
    mHandler = new Handler(Looper.getMainLooper()) {
    ...

在Handler里,覆蓋handleMessage()。Android系統(tǒng)會在Handler管理的線程收到新消息時,調用該方法。一個指定線程的所有Handler對象都會收到相同的消息。

復制代碼 代碼如下:

        /*
         * handleMessage() defines the operations to perform when
         * the Handler receives a new Message to process.
         */
        @Override
        public void handleMessage(Message inputMessage) {
            // Gets the image task from the incoming Message object.
            PhotoTask photoTask = (PhotoTask) inputMessage.obj;
            ...
        }
    ...
    }
}

從任務里移動數(shù)據(jù)到UI線程

要從后臺線程的任務里移動數(shù)據(jù)到UI線程的對象,先保存引用到數(shù)據(jù)和任務對象的UI對象里,接下來把任務對象和狀態(tài)碼傳給Handler對象。在這個對象里,發(fā)送一個包含狀態(tài) 和任務對象的消息給Handler.因為Handler在UI線程上運行,它可以移動數(shù)據(jù)給UI對象。

在任務對象里存儲數(shù)據(jù)

如,這是一個Runnable,運行在后臺線程,它解析Bitmap,并保存到它的父對象。Runnable同時保存狀態(tài)碼DECODE_STATE_COMPLETED。

復制代碼 代碼如下:

// A class that decodes photo files into Bitmaps
class PhotoDecodeRunnable implements Runnable {
    ...
    PhotoDecodeRunnable(PhotoTask downloadTask) {
        mPhotoTask = downloadTask;
    }
    ...
    // Gets the downloaded byte array
    byte[] imageBuffer = mPhotoTask.getByteBuffer();
    ...
    // Runs the code for this task
    public void run() {
        ...
        // Tries to decode the image buffer
        returnBitmap = BitmapFactory.decodeByteArray(
                imageBuffer,
                0,
                imageBuffer.length,
                bitmapOptions
        );
        ...
        // Sets the ImageView Bitmap
        mPhotoTask.setImage(returnBitmap);
        // Reports a status of "completed"
        mPhotoTask.handleDecodeState(DECODE_STATE_COMPLETED);
        ...
    }
    ...
}
...

PhotoTask還包含一個ImageView引用,用來顯示Bitmap.盡管引用Bitmap和ImageView是在同一個對象里,但因為不是在UI線程,你不能直接讓ImageView顯示Bitmap.

沿對象層次逐級發(fā)送狀態(tài)

PhotoTask持有解碼的數(shù)據(jù)和顯示數(shù)據(jù)的View對象的引用,它從PhotoDecodeRunnable接收到狀態(tài)碼,并且沿著線程池里引用的對象和Handler實例傳送。

復制代碼 代碼如下:

public class PhotoTask {
    ...
    // Gets a handle to the object that creates the thread pools
    sPhotoManager = PhotoManager.getInstance();
    ...
    public void handleDecodeState(int state) {
        int outState;
        // Converts the decode state to the overall state.
        switch(state) {
            case PhotoDecodeRunnable.DECODE_STATE_COMPLETED:
                outState = PhotoManager.TASK_COMPLETE;
                break;
            ...
        }
        ...
        // Calls the generalized state method
        handleState(outState);
    }
    ...
    // Passes the state to PhotoManager
    void handleState(int state) {
        /*
         * Passes a handle to this task and the
         * current state to the class that created
         * the thread pools
         */
        sPhotoManager.handleState(this, state);
    }
    ...
}

移動數(shù)據(jù)到UI

PhotoManager從PhotoTask對象接收到狀態(tài)碼和PhotoTask對象的句柄。因為狀態(tài)是TASK_COMPLETE,創(chuàng)建一個包含狀態(tài)和任務對象的Message,發(fā)送給Handler。

復制代碼 代碼如下:

public class PhotoManager {
    ...
    // Handle status messages from tasks
    public void handleState(PhotoTask photoTask, int state) {
        switch (state) {
            ...
            // The task finished downloading and decoding the image
            case TASK_COMPLETE:
                /*
                 * Creates a message for the Handler
                 * with the state and the task object
                 */
                Message completeMessage =
                        mHandler.obtainMessage(state, photoTask);
                completeMessage.sendToTarget();
                break;
            ...
        }
        ...
    }

最終,Handler.handleMessage()為每個進來的Message檢查狀態(tài)碼。如果狀態(tài)碼是TASK_COMPLETE,任務就是完成了,Message里的PhotoTask對象包含Bitmap和ImageView.因為Handler.handleMessage()運行在UI線程,它可以安全地為ImageView設置Bitmap.

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 一区二区三区回区在观看免费视频 | 久久网站热最新地址 | 久久综合九色综合欧美狠狠 | 免费午夜剧场 | 日韩福利| 国产乱码精品一区二区三区忘忧草 | 亚洲国产日韩a在线播放性色 | 国产亚洲精品成人av久久ww | 欧美国产一区二区 | 一区二区亚洲 | 91在线观看免费 | 激情婷婷 | 韩日中文字幕 | 天天操天天舔天天爽 | 欧美久热 | 久久国产精品无码网站 | 日韩有码电影 | 亚洲免费成人 | 成人国产精品一区二区毛片在线 | 亚洲四区 | 超级碰在线 | 免费的色网站 | 国产午夜精品一区二区 | www.精品| 久久久久久国产精品 | 欧美在线视频一区二区 | 男女免费在线观看视频 | 亚洲成人综合视频 | 97人人干| 午夜视频 | 免费一级淫片aaa片毛片a级 | 欧美日韩成人免费 | 91免费国产 | 亚洲精品一区二区三区四区高清 | 五月激情综合网 | 婷婷桃色网| 国产极品美女高潮无套av个 | 国产色av| 凹凸日日摸日日碰夜夜 | 特级理论片 | 性色av网|