Android開發(fā)使用Message對(duì)象分發(fā)必備知識(shí)點(diǎn)詳解
Message的創(chuàng)建
消息Message一般不支持大家直接通過(guò)new的方式進(jìn)行創(chuàng)建的,因?yàn)?code>Message作為Android系統(tǒng)中使用頻率非常高的一個(gè)對(duì)象,如果每次都泛濫的直接創(chuàng)建一個(gè)新的,對(duì)性能是有一定影響的,而通過(guò)對(duì)象池的方式進(jìn)行復(fù)用 ,則是非常好的一種方式。
Message中就提供了這樣的一個(gè)對(duì)象池(最大緩存消息數(shù)量為50):

通過(guò)鏈表的形式將一個(gè)個(gè)待復(fù)用的緩存Message連接起來(lái)。并且提供了obtain()方法負(fù)責(zé)從對(duì)象池中獲取一個(gè)Message:
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
當(dāng)消息調(diào)度完畢時(shí),會(huì)通過(guò)recycleUnchecked()方法進(jìn)行回收并放入到對(duì)象池:
void recycleUnchecked() {
flags = FLAG_IN_USE;
what = 0;
arg1 = 0;
arg2 = 0;
obj = null;
...
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
}
重置要回收的Message的各個(gè)成員屬性,然后添加到對(duì)象池sPool。
消息分發(fā)執(zhí)行的三種方式
消息調(diào)度分發(fā)最終是在Looper.loopOnce()中執(zhí)行,我們看下源碼:
private static boolean loopOnce(final Looper me,
final long ident, final int thresholdOverride) {
Message msg = me.mQueue.next(); // might block
if (msg == null) {
return false;
}
try {
msg.target.dispatchMessage(msg);
}
msg.recycleUnchecked();
return true;
}
核心就是msg.target.dispatchMessage(),我們看下具體的方法邏輯:
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
源碼一目了然,接下來(lái)我們一個(gè)個(gè)的進(jìn)行分析:
- 先檢測(cè)
Message的callback是否為null,不為null就執(zhí)行callback的run方法調(diào)度執(zhí)行,這個(gè)一般是如何傳入的呢:
public final boolean post(@NonNull Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
很熟悉的post()方法就并不再過(guò)多介紹了。
- 然后檢測(cè)
Hander的mCallback是否為null,不為null就執(zhí)行mCallback.handleMessage(),這個(gè)是什么時(shí)候傳入的呢:
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
通過(guò)Handler構(gòu)造方法時(shí)作為構(gòu)造參數(shù)傳入,可以選擇性使用。
- 上面都不滿足,就調(diào)用
Handler自身的handleMessage()方法調(diào)度執(zhí)行,這也是我們常用的消息執(zhí)行的一種方式,一般都是創(chuàng)建Handler對(duì)象時(shí)重寫這個(gè)該方法:
fun test333() {
val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
}
}
}
以上三種消息分發(fā)方式第一種和第三種使用的頻率比較高,第二種這種方式可以作為一種hook的手段攔截某些消息的原本調(diào)度邏輯,實(shí)現(xiàn)功能增強(qiáng)。
比如Activity、Service等組件的調(diào)度是通過(guò)ApplicationThread通過(guò)Handler分發(fā)到主線程進(jìn)行調(diào)度執(zhí)行,如果你想監(jiān)聽其生命周期,就可以通過(guò)上面的第二種方式結(jié)合反射給負(fù)責(zé)分發(fā)的Handler注入一個(gè)mCallback屬性值。
總結(jié)
本篇文章主要是介紹了Message創(chuàng)建的正確方式,以及其如何在Handler中調(diào)度分發(fā)的,每個(gè)流程是什么,希望能給你帶來(lái)幫助。
更多關(guān)于Android開發(fā)Message對(duì)象的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
android實(shí)現(xiàn)簡(jiǎn)單進(jìn)度條ProgressBar效果
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)簡(jiǎn)單進(jìn)度條ProgressBar效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
android中使用SharedPreferences進(jìn)行數(shù)據(jù)存儲(chǔ)的操作方法
本篇文章介紹了,在android中使用SharedPreferences進(jìn)行數(shù)據(jù)存儲(chǔ)的操作方法。需要的朋友參考下2013-04-04
Android中home鍵和back鍵區(qū)別實(shí)例分析
這篇文章主要介紹了Android中home鍵和back鍵區(qū)別,以實(shí)例形式較為詳細(xì)的分析并總結(jié)了home鍵和back鍵區(qū)別及使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
Android studio導(dǎo)入項(xiàng)目的方法詳解(簡(jiǎn)單快速)
最近開課移動(dòng)互聯(lián)網(wǎng)應(yīng)用開發(fā),實(shí)驗(yàn)課老師發(fā)了代碼讓我們導(dǎo)入,在網(wǎng)上找了各種方法,發(fā)現(xiàn)不是每一個(gè)項(xiàng)目都適合,有些能夠成功,有些還是有錯(cuò),頭大的很。后面發(fā)現(xiàn)一個(gè)比較簡(jiǎn)單的方法,沒(méi)翻過(guò)車,新手可以試試2017-06-06
Android開發(fā)Dart?Constructors構(gòu)造函數(shù)使用技巧整理
這篇文章主要為大家介紹了Android開發(fā)Dart?Constructors構(gòu)造函數(shù)使用技巧整理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Kotlin1.6.20新功能Context?Receivers使用技巧揭秘
這篇文章主要為大家介紹了Kotlin1.6.20功能Context?Receivers使用揭秘,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
android開發(fā)教程之使用listview顯示qq聯(lián)系人列表
這篇文章主要介紹了android使用listview顯示qq聯(lián)系人列表的示例,需要的朋友可以參考下2014-02-02
Android的Glide庫(kù)加載圖片的用法及其與Picasso的對(duì)比
這篇文章主要介紹了Android的Glide庫(kù)加載圖片的用法及其與Picasso的對(duì)比,Glide的加載gif圖片的功能和性能受到了很多開發(fā)者的青睞,需要的朋友可以參考下2016-04-04

