android handler工作原理
作用
便於在子線程中更新主UI線程中的控件
這里涉及到了UI主線程和子線程
UI主線程
它很特別。通常我們會認為UI主線程將頁面繪制完成,就結束了。但是它沒有。它在一直默默等待着來自用戶操作控件發生的事件消息。
- 這里的事件和其中包含的信息都被封裝為一個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
消息對象的實體
handler
它的內部實現包含子線程thread、回調函數callback、成員變量looper。
每當handler調用sendMessage()(或者其它類似相關方法)的時候,將會向messageQueue里面添加一個message。添加的時候會去檢查該message與隊列中已經存在的message的when屬性,判斷誰在前誰在后
其實,兩條線程之間的數據交互,一般采用回調方法。handler的實現原理也是依據如此。
具體的使用方法
- 在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里面的消息