Handler是Android一個很基礎的東西了,面試的時候常常問,並且都是問內部原理,是如何傳遞消息的,如今在此記錄一下Handler的消息傳遞機制面試
Handler的用法很簡單,就是直接new一個Handler,而後對這個對象發送消息 主線程中:bash
Message msg = new Message();
handler.sendMessage(msg);
public Handler handler= new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
複製代碼
異步線程中:異步
Message msg = new Message();
handler.sendMessage(msg);
new Thread(){
@Override
public void run() {
super.run();
Looper.prepare();
handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
Looper.loop();
}
};
複製代碼
Handler傳遞消息大概有如下三個步驟:ide
Looper.prepare();oop
這個方法的做用是綁定當前線程post
建立一個MessageQueue this
經過上面的代碼,咱們能夠看到Looper經過調用prepare方法實現了建立一個Looper,而且經過ThreadLocal綁定當前線程和建立了一個MessageQueuespa
handler發送消息到MessageQueue線程
咱們發送消息的時候都是經過handler的send或者post之類的方法來發送消息,可是無論是經過send類型的或者是post類型的,他們都會調用到Handler中的enqueueMessage()方法,這個不貼代碼了,太多了,能夠自行追蹤一下,能夠發現Handler發送消息的方法最終都會調用到sendMessageAtTime()方法,而後在該方法中判斷是否存在MessageQueue,若是存在就調用enqueueMessage()方法3d
Looper.loop(); 該方法上面說了是無限輪詢的去MessageQueue中獲取消息,而後拿到消息後,再經過handler將消息發送回去 代碼太多就截取loop()方法中關鍵的地方吧
這裏咱們能夠關注兩個點,第一,經過當前的Looper將第一步中在構造中建立的MessageQueue獲取到;第二調用MessageQueue的next方法取出消息(在next方法中還進行了時間的判斷,這裏是指延遲發送的,只有達到時間了,纔會喚醒該消息,進行發送) 這裏的msg.target就是Handler,在前面說過了每一個handler在發送消息的時候最終都會通過enqueueMessage()方法,在enqueueMessage()方法中就將當前的handler賦值給了msg.target,而後就是handler調用了dispatchMessage()方法將消息發送出去,而且判斷當前的callback是否爲空,若是不爲空,則調用handlerMessage()方法將消息發出去,咱們在new Handler()時重寫的HandlerMessage()方法就是這個了;在主線程中,咱們沒有調用過Looper.prepare()和Looper.loop()方法,照樣能夠直接給handler發送消息,這是由於在主線程操做管理者(ActivityThread)中已經幫咱們寫好了Looper.prepare()和Looper.loop()方法(注意:loop是一個死循環,loop後面的代碼不會執行,因此從圖片中咱們能夠看到,若是loop後面的執行了,那就報錯了),並且主線程中的Looper是不能夠退出的,退出就會報錯
將 Handler 定義成靜態的內部類,在內部持有 Activity 的弱引用,並及時移除全部消息。
private static class SafeHandler extends Handler {
private WeakReference<HandlerActivity> ref;
public SafeHandler(HandlerActivity activity) {
this.ref = new WeakReference(activity);
}
@Override
public void handleMessage(final Message msg) {
HandlerActivity activity = ref.get();
if (activity != null) {
activity.handleMessage(msg);
}
}
}
//在Activity中移除消息
Override
protected void onDestroy() {
safeHandler.removeCallbacksAndMessages(null);
super.onDestroy();
}
複製代碼
以上是記錄Handler的消息發送機制,以及避免由Handler引發的內存泄漏的解決辦法,總結不徹底確定還有其餘的沒有記錄到的,但願網友們指出!