Android-Handler源碼解析-Handler
源碼版本:
- Handler:SDK-31
導(dǎo)航:
成員變量
// 是否發(fā)現(xiàn)(檢查)潛在的泄漏
private static final boolean FIND_POTENTIAL_LEAKS = false;
// Log的Tag
private static final String TAG = "Handler";
// 主線程Handler
private static Handler MAIN_THREAD_HANDLER = null;
// 此Handler的Looper
@UnsupportedAppUsage
final Looper mLooper;
// 此Handler的消息隊(duì)列,來(lái)自Looper對(duì)象。
final MessageQueue mQueue;
// 此Handler分發(fā)消息時(shí),優(yōu)先處理消息的Callback。
@UnsupportedAppUsage
final Callback mCallback;
// 是否是異步Handler,即是否send或post的消息全部都是異步消息,默認(rèn)為false。
final boolean mAsynchronous;
// 跨進(jìn)程通信,消息發(fā)送者。
@UnsupportedAppUsage
IMessenger mMessenger;
說(shuō)明:
Handler為什么需要持有Looper、MessageQueue,因?yàn)?code>Handler發(fā)送消息等操作需要知道發(fā)送到哪個(gè)MessageQueue,而MessageQueue需要從Looper中獲取,以便發(fā)出的消息能進(jìn)行輪詢分發(fā) 。Looper相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-Looper。MessageQueue相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-MessageQueue。
創(chuàng)建Handler
想要使用Handler,首先要創(chuàng)建Handler,所以我們接下來(lái)看下它是如何被創(chuàng)建的。
new Handler()
默認(rèn)Looper
Handler()
@Deprecated
public Handler() {
this(null, false);
}
Handler(Callback)
@Deprecated
public Handler(@Nullable Callback callback) {
this(callback, false);
}
Handler(Callback, boolean)
/** @hide */
public Handler(@Nullable Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
// 檢查潛在的泄漏
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
// 匿名類(lèi)、成員類(lèi)、局部類(lèi),并且不是靜態(tài)的,警告提示(以下Handler類(lèi)應(yīng)該是靜態(tài)的,否則可能會(huì)發(fā)生泄漏)。
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
// 獲取當(dāng)前線程的Looper
mLooper = Looper.myLooper();
if (mLooper == null) {
// 當(dāng)前線程沒(méi)有Looper,則拋出異常提示(不能在沒(méi)有調(diào)用Looper.prepare()的線程中創(chuàng)建handler)。
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
// 獲取Looper的消息隊(duì)列
mQueue = mLooper.mQueue;
// 記錄CallBack
mCallback = callback;
// 記錄是否是異步的
mAsynchronous = async;
}
以上構(gòu)造方法,使用默認(rèn)的Looper(當(dāng)前線程的Looper)。如果這個(gè)線程沒(méi)有looper,則拋出異常。
說(shuō)明:
Handler()、Handler(Callback)兩個(gè)構(gòu)造方法已經(jīng)被標(biāo)記為@Deprecated(過(guò)時(shí)),因?yàn)樵?code>Handler構(gòu)造過(guò)程中隱式選擇一個(gè)Looper可能會(huì)導(dǎo)致錯(cuò)誤,其中操作會(huì)自動(dòng)丟失(如果Handler不需要新任務(wù)并退出)、崩潰(如果handler有時(shí)是在一個(gè)沒(méi)有激活Looper線程上創(chuàng)建的),或者競(jìng)態(tài)條件,其中handler關(guān)聯(lián)的線程與作者預(yù)期的不符。相反,可以使用java.util.concurrent.Executor,或者使用Looper.getMainLooper,{linkandroid.view.View#getHandler}或類(lèi)似工具顯式指定Looper。如果為了兼容性需要隱藏thread local行為,則使用new Handler(Looper.myLooper())讓讀者更清楚。Handler(Callback, boolean)兩個(gè)構(gòu)造方法已經(jīng)被標(biāo)記為@hide(隱藏),只能系統(tǒng)內(nèi)部使用。- 使用默認(rèn)的
Looper(當(dāng)前線程的Looper),如果這個(gè)線程沒(méi)有looper,則拋出異常。- 參數(shù)
Callback,為此Handler分發(fā)消息時(shí),優(yōu)先處理消息的Callback,詳細(xì)見(jiàn)后面-分發(fā)Message。- 參數(shù)
async,為此Handler發(fā)送消息時(shí),是否全部發(fā)送異步/同步(默認(rèn)同步)消息,詳細(xì)見(jiàn)后面-發(fā)送Message。- 異步消息表示不需要對(duì)同步消息進(jìn)行全局排序的中斷或事件。 異步消息不受
MessageQueue.postSyncBarrier(long)引入的同步屏障的影響。MessageQueue同步屏障相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-MessageQueue-同步屏障。
指定Looper
Handler(Looper)
public Handler(@NonNull Looper looper) {
this(looper, null, false);
}
Handler(Looper, Callback)
public Handler(@NonNull Looper looper, @Nullable Callback callback) {
this(looper, callback, false);
}
Handler(Looper, Callback, boolean)
/** @hide */
@UnsupportedAppUsage
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
以上構(gòu)造方法,使用指定的Looper而不是默認(rèn)的Looper。
說(shuō)明:
Handler(Looper)、Handler(Looper, Callback)兩個(gè)構(gòu)造方法未被標(biāo)記為@Deprecated(過(guò)時(shí)),并使用指定的Looper,推薦使用。Handler(Looper, Callback, boolean)構(gòu)造方法已經(jīng)被標(biāo)記為@hide(隱藏),只能系統(tǒng)內(nèi)部使用。
Handler.createAsync()
Handler.createAsync(Looper)
@NonNull
public static Handler createAsync(@NonNull Looper looper) {
if (looper == null) throw new NullPointerException("looper must not be null");
return new Handler(looper, null, true);
}
Handler.createAsync(Looper, Callback)
@NonNull
public static Handler createAsync(@NonNull Looper looper, @NonNull Callback callback) {
if (looper == null) throw new NullPointerException("looper must not be null");
if (callback == null) throw new NullPointerException("callback must not be null");
return new Handler(looper, callback, true);
}
Handler.createAsync()方法,為靜態(tài)方法,創(chuàng)建一個(gè)異步Handler,其發(fā)布的Message不受同步障礙(如顯示vsync)的影響。
說(shuō)明:
- 發(fā)送到異步
handler的消息可以保證彼此之間的順序,但不一定要按照來(lái)自其他Handlers的消息進(jìn)行排序。
小結(jié)
- 創(chuàng)建-同步
Handler,分為未指定Looper、指定Looper兩種方式創(chuàng)建。
- 未指定
Looper,則使用當(dāng)前線程的Looper,不推薦使用。- 指定
Looper,推薦使用,構(gòu)造方法為Handler(Looper)、Handler(Looper, Callback)。
- 創(chuàng)建-異步
Handler,使用Handler.createAsync(Looper)、Handler.createAsync(Looper, Callback)方法創(chuàng)建。
創(chuàng)建Message
想要使用Message,可以通過(guò)Handler創(chuàng)建Message,所以我們接下來(lái)看下它是如何被創(chuàng)建的。
obtainMessage()
@NonNull
public final Message obtainMessage() {
return Message.obtain(this);
}
@NonNull
public final Message obtainMessage(int what) {
return Message.obtain(this, what);
}
@NonNull
public final Message obtainMessage(int what, @Nullable Object obj) {
return Message.obtain(this, what, obj);
}
@NonNull
public final Message obtainMessage(int what, int arg1, int arg2) {
return Message.obtain(this, what, arg1, arg2);
}
@NonNull
public final Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {
return Message.obtain(this, what, arg1, arg2, obj);
}
以上obtainMessage()方法 ,從全局消息池返回一個(gè)新的消息。內(nèi)部使用Message.obtain()方法創(chuàng)建消息,并將其Message的target為當(dāng)前Handler。
說(shuō)明:
Message.obtain()相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-Message-創(chuàng)建Message。
小結(jié)
handler.obtainMessage()方法,使用Message.obtain()方法創(chuàng)建消息,并將其Message的target為當(dāng)前Handler。
發(fā)送Message
Message創(chuàng)建好后,便可以發(fā)送消息了,Handler除了可以通過(guò)sendMessage()方法發(fā)送消息,還可以通過(guò)post()方法執(zhí)行指定的Callback任務(wù),所以我們接下來(lái)看下它們是如何被發(fā)送的。
send-Message
sendMessage()
public final boolean sendMessage(@NonNull Message msg) {
return sendMessageDelayed(msg, 0);
}
sendEmptyMessage()
public final boolean sendEmptyMessage(int what) {
return sendEmptyMessageDelayed(what, 0);
}
sendEmptyMessageDelayed()
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
sendEmptyMessageAtTime()
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageAtTime(msg, uptimeMillis);
}
sendMessageDelayed()
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
sendMessageAtTime()
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
sendMessageAtFrontOfQueue()
public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, 0);
}
以上方法,為發(fā)送立即消息、發(fā)送延遲消息、發(fā)送指定時(shí)刻消息、將消息排在消息隊(duì)列的前面。
說(shuō)明:
sendMessage()、sendEmptyMessage()為發(fā)送立即消息消息,sendMessageDelayed()、sendEmptyMessageDelayed()為發(fā)送延遲消息消息,sendMessageAtTime()為發(fā)送指定時(shí)刻消息,sendMessageAtFrontOfQueue()為將消息排在消息隊(duì)列的前面。sendMessageAtFrontOfQueue(),為將消息排在消息隊(duì)列的前面,以便在消息loop的下一次迭代中處理。此方法僅用于非常特殊的情況——它很容易使消息隊(duì)列挨餓、導(dǎo)致排序問(wèn)題或產(chǎn)生其它意想不到的副作用。- 發(fā)送立即消息、發(fā)送延遲消息、指定時(shí)刻發(fā)送、將消息排在消息隊(duì)列的前面,他們最終調(diào)用的都是
enqueueMessage()方法。
我們接下來(lái)看下enqueueMessage()方法。
enqueueMessage()
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
// 指定Message的Handler為此Handler
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
// 如果此Handler是異步的,則發(fā)送的所有消息都是異步的。
if (mAsynchronous) {
msg.setAsynchronous(true);
}
// 使用MessageQueue將消息加入到消息隊(duì)列中
return queue.enqueueMessage(msg, uptimeMillis);
}
enqueueMessage()方法,為將Message加入到MessageQueue中。
說(shuō)明:
- 指定此
Message的target為此Handler,使此Message和此Handler關(guān)聯(lián),以便使用此Handler處理此Message。- 如果此
Handler是異步的,則發(fā)送的所有消息都是異步的。uptimeMillis參數(shù)為消息執(zhí)行時(shí)刻,立即執(zhí)行的為SystemClock.uptimeMillis(),延時(shí)執(zhí)行的為SystemClock.uptimeMillis() + delayMillis,指定時(shí)刻發(fā)送的為指定的,將消息排在消息隊(duì)列的前面的為0。MessageQueue入隊(duì)消息相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-MessageQueue-入隊(duì)Message。
post-Callback
post()
public final boolean post(@NonNull Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
postAtTime()
public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {
return sendMessageAtTime(getPostMessage(r), uptimeMillis);
}
public final boolean postAtTime(@NonNull Runnable r, @Nullable Object token, long uptimeMillis) {
return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
}
postDelayed()
public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
public final boolean postDelayed(@NonNull Runnable r, @Nullable Object token, long delayMillis) {
return sendMessageDelayed(getPostMessage(r, token), delayMillis);
}
postAtFrontOfQueue()
public final boolean postAtFrontOfQueue(@NonNull Runnable r) {
return sendMessageAtFrontOfQueue(getPostMessage(r));
}
以上方法,為執(zhí)行指定的Callback任務(wù),由Runnable實(shí)現(xiàn)。底層也是通過(guò)getPostMessage()方法將Runnable包裝為Message然后調(diào)用對(duì)應(yīng)的發(fā)送消息的方法進(jìn)行發(fā)送,發(fā)送消息詳細(xì)看上面的-send-Message。
接下來(lái)我們來(lái)看一下getPostMessage()方法的實(shí)現(xiàn)。
getPostMessage()
private static Message getPostMessage(Runnable r) {
// 使用復(fù)用獲取新的Message
Message m = Message.obtain();
// 將Runnable保存到Message的callback中
m.callback = r;
return m;
}
@UnsupportedAppUsage
private static Message getPostMessage(Runnable r, Object token) {
Message m = Message.obtain();
m.obj = token;
m.callback = r;
return m;
}
getPostMessage()方法,使用復(fù)用機(jī)制獲取新的Message,并將Runnable保存到Message的callback中。
小結(jié)
- 發(fā)送消息分為
send-Message、post-Callback,post-Callback底層也是通過(guò)send-Message進(jìn)行發(fā)送(將Runnable保存到Message的callback中)。sendMessageAtFrontOfQueue()、postAtFrontOfQueue(),方法為將消息排在消息隊(duì)列的前面,會(huì)使原來(lái)有序的隊(duì)列變?yōu)?strong>無(wú)序的,謹(jǐn)慎使用。- 通過(guò)
handler發(fā)送的消息,最終都會(huì)將此Message和此Handler關(guān)聯(lián),以便使用此Handler處理此Message。- 如果此
Handler是異步的,則發(fā)送的所有消息都是異步的。
分發(fā)Message
當(dāng)Looper.loop()方法開(kāi)啟后,并且此Looper的MessageQueue的next()方法返回一個(gè)Message后,會(huì)調(diào)用Handler的dispatchMessage()方法,代碼如下。
Loop->loopOnce()
private static boolean loopOnce(final Looper me,
final long ident, final int thresholdOverride) {
Message msg = me.mQueue.next(); // might block
...
// 調(diào)用Handler分發(fā)消息
msg.target.dispatchMessage(msg);
...
}
接下來(lái)我們來(lái)看一下Handler的dispatchMessage()方法。
dispatchMessage()
Handler->dispatchMessage()
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
// 處理Callback
handleCallback(msg);
} else {
// 處理Message
if (mCallback != null) {
// handler的Callback不為空,優(yōu)先它處理。
if (mCallback.handleMessage(msg)) {
// 返回true,表示handler的Callback已經(jīng)處理,不再需要handleMessage()方法處理。
return;
}
}
// 使用handleMessage方法處理
handleMessage(msg);
}
}
dispatchMessage()方法,為分發(fā)消息,分為處理Callback、處理Message,而的處理Message優(yōu)先handler的Callback處理,其次再handleMessage()方法處理。
說(shuō)明:
dispatchMessage()方法為public并且不是final,所以可以被覆寫(xiě),一般不覆寫(xiě)此方法。
接下來(lái)我們先來(lái)看一下處理Callback的handleCallback()方法。
handleCallback()
private static void handleCallback(Message message) {
// 調(diào)用callback.run()方法(即runnable.run()方法)執(zhí)行
message.callback.run();
}
handleCallback()方法,直接調(diào)用message的callback(即Runnable)的run()方法執(zhí)行。
接下來(lái)我們?cè)賮?lái)看一下優(yōu)先處理Message的Handler.Callback類(lèi),其次再來(lái)看一下其次處理的handleMessage()方法。
Handler.Callback類(lèi)
public interface Callback {
/**
* @return 如果不需要進(jìn)一步處理,則為T(mén)rue。
*/
boolean handleMessage(@NonNull Message msg);
}
如果handler.mCallback有設(shè)置值,則優(yōu)先它來(lái)處理,并且handleMessage()方法返回true,則不再需要handleMessage()方法處理。
handleMessage()
public void handleMessage(@NonNull Message msg) {
}
handleMessage()方法,為處理消息,我們可以通過(guò)Message的what的值來(lái)區(qū)分,來(lái)實(shí)現(xiàn)自己的邏輯。
說(shuō)明:
handleMessage()方法為public并且不是final,所以可以被覆寫(xiě),一般覆寫(xiě)此方法。
小結(jié)
- 分發(fā)
Message,它是通過(guò)Handler的dispatchMessage()方法進(jìn)行分發(fā)處理。- 分發(fā)
Message,它分為處理Callback、處理Message。
2.1.處理Callback,直接調(diào)用callback(即Runnable)的run()方法執(zhí)行。
2.2.處理Message,優(yōu)先handler的Callback處理,其次再handleMessage()方法處理。dispatchMessage()、handleMessage()方法均可以被覆寫(xiě),一般只覆寫(xiě)handleMessage()方法即可。
移除Messages、Callbacks
removeMessages()
public final void removeMessages(int what) {
mQueue.removeMessages(this, what, null);
}
public final void removeMessages(int what, @Nullable Object object) {
mQueue.removeMessages(this, what, object);
}
removeCallbacks()
public final void removeCallbacks(@NonNull Runnable r) {
mQueue.removeMessages(this, r, null);
}
public final void removeCallbacks(@NonNull Runnable r, @Nullable Object token) {
mQueue.removeMessages(this, r, token);
}
removeCallbacksAndMessages()
public final void removeCallbacksAndMessages(@Nullable Object token) {
mQueue.removeCallbacksAndMessages(this, token);
}
以上方法,為移除指定what的Message或指定runnable的Callbacks,全部都是通過(guò)調(diào)用MessageQueue的removeXX方法進(jìn)行移除。
說(shuō)明:
MessageQueue移除消息相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-MessageQueue-移除Message。
小結(jié)
- 移除
Messages、Callbacks,removeMessages()、removeCallbacks()、removeCallbacksAndMessages()方法,分別為移除所有符合條件的Messages、Callbacks。
是否有Messages、Callbacks
hasMessages()
public final boolean hasMessages(int what) {
return mQueue.hasMessages(this, what, null);
}
hasCallbacks()
public final boolean hasCallbacks(@NonNull Runnable r) {
return mQueue.hasMessages(this, r, null);
}
hasMessagesOrCallbacks()
public final boolean hasMessagesOrCallbacks() {
return mQueue.hasMessages(this);
}
以上方法,為判斷是否有指定what的Message或指定runnable的Callbacks,全部都是通過(guò)調(diào)用MessageQueue的hasMessages方法進(jìn)行判斷。
說(shuō)明:
MessageQueue是否有消息相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-MessageQueue-是否有Message。
小結(jié)
- 是否有
Messages、Callbacks,hasMessages()、hasCallbacks()、hasMessagesOrCallbacks()方法,分別為判斷是否有符合條件的Messages、Callbacks。
其它
getMessageName()
public String getMessageName(@NonNull Message message) {
if (message.callback != null) {
// 是Callback類(lèi)型,返回此Callback(即Runnable)的類(lèi)名。
return message.callback.getClass().getName();
}
// 是Message類(lèi)型,返回此Message的what的十六進(jìn)制。
return "0x" + Integer.toHexString(message.what);
}
獲取表示指定Message名稱(chēng)的字符串。默認(rèn)實(shí)現(xiàn),是Callback類(lèi)型返回此Callback(即Runnable)的類(lèi)名,是Message類(lèi)型返回此Message的what的十六進(jìn)制。
getLooper()
@NonNull
public final Looper getLooper() {
return mLooper;
}
獲取此Handler的Looper對(duì)象
dump()
public final void dump(@NonNull Printer pw, @NonNull String prefix) {
pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
if (mLooper == null) {
pw.println(prefix + "looper uninitialized");
} else {
mLooper.dump(pw, prefix + " ");
}
}
轉(zhuǎn)儲(chǔ)looper的狀態(tài),以進(jìn)行調(diào)試。如果Looper為空,直接打印,否則調(diào)用Looper的dump()方法。
說(shuō)明:
Looper轉(zhuǎn)儲(chǔ)的相關(guān)介紹,請(qǐng)看Android-Handler源碼解析-Looper-其它。
總結(jié)
以上就是Handler源碼的Handler源碼部分,Handler其它源碼部分看下面導(dǎo)航。之后會(huì)出其它Android源碼系列,請(qǐng)及時(shí)關(guān)注。如果你有什么問(wèn)題,大家評(píng)論區(qū)見(jiàn)!
導(dǎo)航:
最后推薦一下我的網(wǎng)站,開(kāi)發(fā)者的技術(shù)博客: devbolg.cn ,目前包含android相關(guān)的技術(shù),之后會(huì)面向全部開(kāi)發(fā)者,歡迎大家來(lái)體驗(yàn)!