一、線程間通訊的Message機制
1、Message介紹
frameworks\base\core\java\android\Os\Message.java
Message是線程之間傳遞資訊的載體,包含了對訊息的描述和任意的資料對象。Message中包含了兩個額外的 int欄位和一個object欄位,這樣在大部分情況下,使用者就不需要再做記憶體配置工作了。雖然Message的建構函式是public的,但是最好是使用Message.obtain( )或Handler.obtainMessage( )函數來擷取Message對象,因為Message的實現中包含了回收再利用的機制,可以提供效率。
2、MessageQueue介紹
frameworks\base\core\java\android\Os\MessageQueue.java
MessageQueue用來容納Message隊列的,其中的Message是由Looper來分發的,Message不能直接添加到MessageQueue中,而是要通過與Looper關聯的Handler去添加。
3、Looper
frameworks\base\core\java\android\Os\Looper.java
Looper是線程用來運行訊息迴圈的。線程本身是沒有訊息迴圈的,需要線上程中調用perpare函數,然後調用loop去處理訊息。在Android中,系統在啟動主線程的時候會自動為之建立一個Looper。
建立本線程的Looper:
public static final void prepare()
運行本線程的Looper:
public static final void loop()
擷取本線程的Looper:
public static final Looper myLooper()
擷取主線程的Looper:
public synchronized static final Looper getMainLooper()
4、Handler
frameworks\base\core\java\android\Os\Handler.java
Handler是用來發送和處理與線程相關聯的Message和Runnable對象的。每個Handler都與一個單獨的線程以及線程訊息佇列相關聯的。當你建立Handler時,Handler就與線程以及線程訊息佇列綁定了,從那以後,Handler就可以將 Message和Runnable發送給對應的訊息佇列,並且能夠處理從訊息佇列中出來的訊息。
Handler提供了使用者需要調用的大部分介面
A、建立Handler:
建立與本地線程相關聯的Handler:
3 |
public Handler(Callback callback) |
建立與指定線程相關聯的Handler:
1 |
public Handler(Looper looper) |
3 |
public Handler(Looper looper, Callback callback) |
B、建立訊息
1 |
public final
Message obtainMessage() |
3 |
public final
Message obtainMessage( int
what) |
5 |
public final
Message obtainMessage( int
what, Object obj) |
7 |
public final
Message obtainMessage( int
what, int arg1,
int arg2) |
9 |
public final
Message obtainMessage( int
what, int arg1,
int arg2, Object obj) |
C、刪除訊息
刪除在訊息佇列中未處理的訊息
1 |
public final
void removeMessages( int
what) |
3 |
public final
void removeMessages( int
what, Object object) |
D、發送訊息
1 |
public final
boolean sendMessage(Message msg) |
3 |
public final
boolean sendMessageDelayed(Message msg,
long delayMillis) |
5 |
public final
boolean post(Runnable r) |
7 |
public final
boolean postDelayed(Runnable r,
long delayMillis) |
E、處理訊息
在Looper的loop函數中迴圈取出MessageQueue的接收訊息佇列中的訊息,然後調用Hander的dispatchMessage函數對訊息進行處理,至於如何處理(相應訊息)則由使用者指定(三個方法,優先順序從高到低:Message裡面的Callback,一個實現了Runnable介面的對象,其中run函數做處理工作;Handler裡面的mCallback指向的一個實現了Callback介面的對象,裡面的handleMessage進行處理;處理訊息 Handler對象對應的類繼承並實現了其中handleMessage函數,通過這個實現的handleMessage函數處理訊息)。
01 |
public void
dispatchMessage(Message msg) { |
03 |
if (msg.callback !=
null ) { |
08 |
if
(mCallback != null ) { |
09 |
if
(mCallback.handleMessage(msg)) { |
二、Message機制的用途
Message機制有兩種用途:
定時執行:延遲到指定時間執行訊息調度
線程通訊:將某些操作在其他線程中排隊執行
1、定時執行
通過本線程的Handler將訊息延遲到指定時間執行,相當於定時器的作用
1 |
public final
boolean sendMessageDelayed(Message msg,
long delayMillis) |
3 |
public final
boolean postDelayed(Runnable r,
long delayMillis) |
還可以在指定時間到期之前,通過removeMessages取消執行
2、線程通訊
Android的UI是單線程的,Android希望UI線程能夠給予User快速的反應,如果UI線程花費太多的時間做幕後的事情,吵過5秒鐘,Android就會給出錯誤提示。因此為了避免拖住UI,一下較費時的工作應該交給獨立的線程去執行。但是如果幕後的線程來執行UI對象,Android又會發出錯誤資訊,所以UI線程與幕後線程需要進行通訊。UI線程將工作分發給幕後線程,幕後線程執行後將相應的狀態返回給UI線程,讓UI線程對UI做成相應的更新。