本節(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對象。如:
在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。
PhotoTask還包含一個ImageView引用,用來顯示Bitmap.盡管引用Bitmap和ImageView是在同一個對象里,但因為不是在UI線程,你不能直接讓ImageView顯示Bitmap.
沿對象層次逐級發(fā)送狀態(tài)
PhotoTask持有解碼的數(shù)據(jù)和顯示數(shù)據(jù)的View對象的引用,它從PhotoDecodeRunnable接收到狀態(tài)碼,并且沿著線程池里引用的對象和Handler實例傳送。
移動數(shù)據(jù)到UI
PhotoManager從PhotoTask對象接收到狀態(tài)碼和PhotoTask對象的句柄。因為狀態(tài)是TASK_COMPLETE,創(chuàng)建一個包含狀態(tài)和任務對象的Message,發(fā)送給Handler。
最終,Handler.handleMessage()為每個進來的Message檢查狀態(tài)碼。如果狀態(tài)碼是TASK_COMPLETE,任務就是完成了,Message里的PhotoTask對象包含Bitmap和ImageView.因為Handler.handleMessage()運行在UI線程,它可以安全地為ImageView設置Bitmap.
新聞熱點
疑難解答
圖片精選