Handler 學(xué)習(xí)
在Android系統(tǒng)中,Handler 是常用的異步消息機(jī)制。最近在改項(xiàng)目中Lint出來(lái)的問(wèn)題,順便查了一下Handler的相關(guān)資料,記錄這個(gè)筆記。
要點(diǎn)總結(jié)
- 每個(gè)線程中只有一個(gè)Looper對(duì)象,而Looper對(duì)象含有一個(gè)MessageQueue對(duì)象,每個(gè)線程可以含有多個(gè)handler對(duì)象;
- App初始化時(shí),會(huì)執(zhí)行ActivityThread的main方法,在main方法中調(diào)用
Looper.prepareMainLooper();
Looper.loop();
進(jìn)行主線程的Looper初始化;而子線程的Looper初始化需要手動(dòng)寫(xiě)Looper.prepare()實(shí)現(xiàn)(似乎 Android 5.0之后不用手動(dòng)調(diào)用。
Looper的初始化方法中,綁定了當(dāng)前線程和新建一個(gè)MessageQueue對(duì)象;
Looper初始化后,需要調(diào)用Looper.loop()方法讓其運(yùn)行起來(lái)。在主線程中,這個(gè)方法會(huì)被系統(tǒng)自動(dòng)調(diào)用;子線程中需要自己進(jìn)行調(diào)用。(似乎 Android 5.0之后不用手動(dòng)調(diào)用);
多個(gè)Message通過(guò)其自身的.next屬性形成一個(gè)隊(duì)列(類(lèi)似與C語(yǔ)言的鏈表),而MessageQueue對(duì)象對(duì)此隊(duì)列進(jìn)行管理。
每個(gè)Handler的handleMessage()方法都是執(zhí)行在初始化該對(duì)象的線程中,而其它方法執(zhí)行在任意線程;
使用Handler發(fā)送消息,最終都會(huì)調(diào)用帶有系統(tǒng)時(shí)間的參數(shù)的方法,而消息隊(duì)列中,消息的排序就是根據(jù)系統(tǒng)時(shí)間進(jìn)行排序;
-
Handler的post()方法、View的post方法和Activity的runOnUiThread()方法,都是調(diào)用了Handler的發(fā)送消息方法。
Activity的:
@Override public final void runOnUiThread(Runnable action) { if (Thread.currentThread() != mUiThread) { mHandler.post(action); } else { action.run(); } }
View的:
public boolean post(Runnable action) { final AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { return attachInfo.mHandler.post(action); } // Postpone the runnable until we know on which thread it needs to run. // Assume that the runnable will be successfully placed after attach. getRunQueue().post(action); return true; }
Handler的:
public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); }
Handler的使用容易引起內(nèi)存泄漏,一般Android Studio會(huì)提示你進(jìn)行弱引用。