android handler工做原理
做用
便於在子線程中更新主UI線程中的控件
這裏涉及到了UI主線程和子線程android
UI主線程
它很特別。一般咱們會認爲UI主線程將頁面繪製完成,就結束了。可是它沒有。它在一直默默等待着來自用戶操做控件發生的事件消息。ide
- 這裏的事件和其中包含的信息都被封裝爲一個message,它是Parcelable對象。
- 主線程不能同時處理全部的事件,這個時候就須要一個存放消息的隊列message queue
- 它裏面包含了一個叫looper,用來管理這個消息池子
- handler在其中負責發送和處理事件
- 去查看Activity中的源碼,會發現它會本身建立一個final類型的handler,還有looper的身影。
looper
- 這個用來管理messageQueue的,主要的執行方法在looper.loop()方法中。你們都這麼說
- UI主線程會給本身建立一個looper對象。子線程的looper須要手動的建立。
- 當handler在UI主線程上進行實例化的時候,自動持有主線程的looper。
messageQueue
它叫隊列,以前覺得它裏面會有Array或者List之類的,可是在源碼裏面沒有看到。
它隊列的實現,是經過message對象中的屬性變量next,來指向下一個message函數
message
消息對象的實體oop
handler
它的內部實現包含子線程thread、回調函數callback、成員變量looper。
每當handler調用sendMessage()(或者其它相似相關方法)的時候,將會向messageQueue裏面添加一個message。添加的時候會去檢查該message與隊列中已經存在的message的when屬性,判斷誰在前誰在後
其實,兩條線程之間的數據交互,通常採用回調方法。handler的實現原理也是依據如此。ui
具體的使用方法
- 在UI主線程中調用沒有參數的構造方法建立Handler的時候,使用的looper對象就是主線程的Looper
- 在子線程中調用沒有參數的構造方法建立handler的時候,須要主動建立looper對象:Looper.prepare()方法;否則在運行的時候就會報錯說"Can't create handler inside thread that has not called Looper.prepare()"
- 在子線程中能夠將主線程的looper做爲構造方法的參數建立handler,就不須要在子線程中建立本身的looper了。這個時候回調方法handleMessage(Message msg)方法將會放在主線程中執行,因此這裏面不要放特別耗時的操做。
Handler mHandler =new Handler(Looper.getMainLooper())
- 在activity中的handler中含有未執行的delay消息的時候,調用activity.onFinish()方法以後,onDestory()不會馬上被調用。因此通常狀況下,在調用onFinish()方法的時候須要清理一下mhandler裏面的消息