Android後台線程和UI線程通訊執行個體_Android

來源:互聯網
上載者:User

本節向你展示如何在任務中發送資料給UI線程裡的對象,這個特性允許你在後台線程工作,完了在UI線程展示結果。

在UI線程定義一個Handler

Handler是Android系統線程管理架構裡的一部分。一個Handler對象接收訊息,並且運行代碼來處理訊息。正常情況下,你為新線程建立Handler,但你也可以為已有的線程建立一個Handler.當你串連Handler到UI線程時,處理訊息的代碼會在UI線程上運行.

在建立線程池的類的構造器裡執行個體化Handler對象,儲存在全域變數裡。用Handler(Looper)方法執行個體化,串連到UI線程,構造方法使用Looper對象,也是Android系統線程管理架構裡的一部分.Looper類有一個靜態方法getMainLooper()可以擷取UI線程的Looper對象。如:

複製代碼 代碼如下:

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

在Handler裡,覆蓋handleMessage()。Android系統會在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;
            ...
        }
    ...
    }
}

從任務裡移動資料到UI線程

要從後台線程的任務裡移動資料到UI線程的對象,先儲存引用到資料和任務對象的UI對象裡,接下來把任務對象和狀態代碼傳給Handler對象。在這個對象裡,發送一個包含狀態 和任務對象的訊息給Handler.因為Handler在UI線程上運行,它可以移動資料給UI對象。

在任務對象裡儲存資料

如,這是一個Runnable,運行在後台線程,它解析Bitmap,並儲存到它的父物件。Runnable同時儲存狀態代碼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.

沿對象層次逐級發送狀態

PhotoTask持有解碼的資料和顯示資料的View對象的引用,它從PhotoDecodeRunnable接收到狀態代碼,並且沿著線程池裡引用的對象和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);
    }
    ...
}

移動資料到UI

PhotoManager從PhotoTask對象接收到狀態代碼和PhotoTask對象的控制代碼。因為狀態是TASK_COMPLETE,建立一個包含狀態和任務對象的Message,發送給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檢查狀態代碼。如果狀態代碼是TASK_COMPLETE,任務就是完成了,Message裡的PhotoTask對象包含Bitmap和ImageView.因為Handler.handleMessage()運行在UI線程,它可以安全地為ImageView設定Bitmap.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.