- 目錄
- Handler廓握、Looper搅窿、MessageQueue源碼解析——Handler
- Handler、Looper隙券、MessageQueue源碼解析——Looper
- Handler男应、Looper、MessageQueue源碼解析——ThreadLocal
- Handler娱仔、Looper沐飘、MessageQueue源碼解析——MessageQueue
Handler
Handler 是Android中常用的異步通信的一個類,Android是一個消息驅動的操作系統(tǒng)牲迫,各種類型的消息都是由Handler發(fā)出耐朴,再由Handler處理,那么對于Handler機制的理解就至關重要盹憎。
比如我們讓一個TextView延時3秒顯示"Hello World"筛峭,我們會這樣寫:
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mTextView.setText("Hello World");
}
}, 3000);```
當我們new 一個Handler時,具體做了什么呢陪每?從源碼中我們可以得到
答案:
Handler共有7種構造方法:
```java
Handler()
Handler(Callback callback)
Handler(Looper looper)
Handler(Looper looper, Callback callback)
/**@hide*/
Handler(boolean async)
/**@hide*/
Handler(Callback callback, boolean async)
/**@hide*/
Handler(Looper looper, Callback callback, boolean async)```
(注意@hide注解影晓,表示這些API是不對外開放的,但是在運行的時候是可以使用這些API檩禾。雖然也是public的俯艰,但是不能直接調用,也無法通過反射獲取锌订。所以我們在使用Handler時只能用前四個構造方法。)
根據(jù)傳入?yún)?shù)的不同画株,最后都會調用這兩個構造方法:
``` java
//沒有傳Looper
Handler(Callback callback, boolean async)
//傳了Looper
Handler(Looper looper, Callback callback, boolean async)```
至于Looper是什么辆飘,接下來再解釋。
看一下```Handler(Callback callback, boolean async)```這個構造函數(shù):
``` java
final Looper mLooper;
final MessageQueue mQueue;
final Callback mCallback;
final boolean mAsynchronous;
...
public Handler(Callback callback, boolean async) {
//檢查Handler類型谓传,提示是否出現(xiàn)內存泄漏warning
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());
}
}
// 得到Looper對像蜈项,稍后解釋
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
//獲得MessageQueue對象
mQueue = mLooper.mQueue;
//設置callback
mCallback = callback;
mAsynchronous = async;
}```
首先通過```Looper.myLooper()```獲得Looper對象,再通過Looper對象獲取與Looper綁定的MessageQueue對象续挟。
那么```Handler(Looper looper, Callback callback, boolean async)```這個構造函數(shù)呢紧卒?
``` java
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}```
沒錯,區(qū)別就是Looper對象通過我們傳進來的Looper對象來指定诗祸。
既然Handler是發(fā)送消息和處理消息的跑芳,那么Handler是怎么發(fā)送消息的呢?
官方為我們提供了這些方法:
```java
public final boolean post(Runnable r)
public final boolean postAtTime(Runnable r, long uptimeMillis)
public final boolean postDelayed(Runnable r, long delayMillis)
public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
public final boolean sendMessage(Message msg)
public final boolean sendEmptyMessage(int what)
public final boolean sendEmptyMessageDelayed(int what, long delayMillis)
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis)
public final boolean sendMessageDelayed(Message msg, long delayMillis)
public boolean sendMessageAtTime(Message msg, long uptimeMillis)```
看起來很多直颅,其實最后都調用了一個方法```sendMessageAtTime(Message msg, long uptimeMillis)```博个。
什么?道理我都懂功偿,post(Runnable r)是個什么東西盆佣?
其實post一系列方法最后調用的還是```sendMessageAtTime(Message msg, long uptimeMillis)```。
但是第一個參數(shù)傳進去的是getPostMessage(r)
``` java
private static Message getPostMessage(Runnable r) {
//從Message pool里獲得一個Message或者新建一個Message對象
Message m = Message.obtain();
m.callback = r;
return m;
}
可以看出Runnable是Message的callback。Runnable callback
是Message的一個成員變量共耍,所以postXXX方法就是對Message的一個封裝虑灰。
那么我們重點看一下sendMessageAtTime方法。
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
//從Looper中獲得的MessageQueue
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}s
return enqueueMessage(queue, msg, uptimeMillis);
}```
最后調用enqueueMessage方法:
``` java
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}```
target是Message的一個Handler類型的成員變量痹兜。所以sendMessageAtTime方法就是獲取MessageQueue穆咐,并為Message對象設置target屬性,然后把message插入到MessageQueue中佃蚜。
Handler也提供了另外兩個方法庸娱,直接把消息插入到消息隊列第一個:
```java
public final boolean postAtFrontOfQueue(Runnable r)
public final boolean sendMessageAtFrontOfQueue(Message msg)```
說完了發(fā)送消息,接下來說一下處理消息谐算。
在Looper的 ``` loop()``` (開啟消息循環(huán))方法有這樣一段代碼:
try {
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}```
我們已經(jīng)知道m(xù)essage的target是一個Handler對象熟尉,消息的處理也就是調用了Handler的dispathMessage方法:
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}```
首先判斷message的callback是否為空,即我們通過postXXX方法發(fā)送的消息會給Message加上一個callback即Runnable洲脂,如果不為空調用handleCallback(msg):
``` java
private static void handleCallback(Message message) {
message.callback.run();
}```
也就是調用Runnable的run()方法斤儿。
如果Message的Callback為空,接下來判斷mCallback是否為空恐锦,mCallback是什么呢往果,回到Handler的構造方法,當我們調用這兩個構造方法```Handler(Callback callback) , Handler(Looper looper, Callback callback)```時一铅,我們會為Handler指定一個callback陕贮,當Handler的callback不為空,會執(zhí)行callback的handleMessage方法潘飘,如果callback為空肮之,則執(zhí)行Handler的handleMessage方法,這兩個方法的實現(xiàn)都為空卜录,需要我們自己去實現(xiàn)戈擒。
Handler的源碼大部分就是這么多,其余的就是一些removeCallback之類的方法艰毒。Handler的主要功能就是這些筐高。接下來我們來學習其他兩個很重要的類Looper。