android訊息機制主要涉及到以下內容:Message, Looper,Handler。
其原理為:訊息線程(預設是主線程,也就是UI線程),維護一個訊息迴圈和一個訊息佇列,
背景工作執行緒向訊息佇列中添加訊息,訊息迴圈從隊列中取出訊息並處理。其中Looper類負責訊息迴圈
和訊息佇列,Message類是訊息的載體,Handler類負責訊息佇列中添加訊息和訊息的處理。
Looper的prepare介面負責為調用線程建立一個Looper對象,下面是android源碼,漢字部分為
本文添加的注釋:
public static final void prepare() {
if (sThreadLocal.get() != null) { //其中sThreadLocal為ThreadLocal對象,不熟悉ThreadLocal的同學可以google下
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
Looper的loop介面負責開啟訊息迴圈:
/**
* Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
*/
public static final void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;//loop中維護的訊息佇列
while (true) {
Message msg = queue.next(); // 從訊息佇列中取訊息
//if (!me.mRun) {
// break;
//}
if (msg != null) {
if (msg.target == null) {
// No target is a magic identifier for the quit message.
return;
}
if (me.mLogging!= null) me.mLogging.println(
">>>>> Dispatching to " + msg.target + " "
+ msg.callback + ": " + msg.what
);
msg.target.dispatchMessage(msg); //訊息處理
if (me.mLogging!= null) me.mLogging.println(
"<<<<< Finished to " + msg.target + " "
+ msg.callback);
msg.recycle();
}
}
}
Handler中維護一個對Looper對象的引用,並直接擷取它的訊息佇列,以便向訊息佇列中添加訊息:
/**
* Default constructor associates this handler with the queue for the
* current thread.
*
* If there isn't one, this handler won't be able to receive messages.
*/
public Handler() {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mLooper = Looper.myLooper(); //擷取線程的Looper對象
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue; //直接擷取Looper對象的訊息佇列
mCallback = null;
}
Looper.loop方法中有一句代碼msg.target.dispatchMessage(msg)(見上文)即是調用Handler的
dispatchMessage方法:
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg); //調用子類的重寫方法,故繼承Handler時要重寫該方法
}
}
清楚了訊息機制後,就不難理解訊息機制的用法了:
MyHandler extends Handler{
public void handleMessage(final Message msg){
switch(msg.what){
case 1:
//做一些具體處理,比如說更新UI等
break;
}
}
}
MyHandler mHandler=new MyHandler();
Message msg = Message.obtain(mHandler,1);
msg.sendToTarget();