Handler 作爲 Android 經常使用組件之一,幾乎每一個應用程序都會使用。Handler 主要有兩個做用,一是當咱們須要按照順序執行多個程序時,二是當咱們在非主線程中更新UI的時候。java
當咱們須要經過 Handler 執行一段代碼時,可使用 post(Runnable)
, postAtTime(java.lang.Runnable, long)
, postDelayed(Runnable, Object, long)
加入一個Runnable
, 或者是使用sendEmptyMessage(int)
, sendMessage(Message)
, sendMessageAtTime(Message, long)
, sendMessageDelayed(Message, long)
發送Message
。但它們最終都會加入一個 MessageQueue
中,而後由 MessageQueue
所在的線程執行。oop
Handler
之因此能工做,是由於有 Looper
, 一個線程最多隻能有一個 Looper
, 也能夠沒有。在建立 Handler
的時候,能夠指定 Looper
, 也能夠不指定,若是不指定則默認使用當前線程的 Looper
, 固然前提是當前線程有Looper
, 若是沒有,則建立Handler
會拋出異常,而主線程默認是有 Looper
的。post
須要注意的是,加入 Handler 的任務不會當即執行,若是 Hander 中 Looper 所在線程當前正忙,則可能要等到這個線程不忙的時候纔會執行經過 Handler 加入的任務。有些開發人員在開發的時候,會把全部須要主線程執行的任務都經過Handler加入,即便當前已是在主線程中了,是的,就是在主線中經過Handler加入一個須要在主線程中執行的任務,而又指望能加入的任務能當即執行,但恐指望會落空。由於正如上面所說,加入Handler的任務可能並不會當即執行,這要取決於當地主線程是否在忙。大多數狀況下,主線程是比較空閒的,一般咱們只在更新UI的時候纔會用到主線程,可是在一些較爲複雜的項目中,就連開發者本身也不清楚主線程在幹什麼,他們只有在發現系統卡頓的時候纔會去關心主線程。spa
爲了不上面這種狀況,其實也很簡單,咱們只要判斷當前線程是否主線程,若是是就當即執行,不然才加入Handler。線程
在主線程中運行的例子:code
private void runOnMainThread(Runnable runnable) {
if (Looper.myLooper() == Looper.getMainLooper()) {
runnable.run();
} else {
mHandler.post(runnable);
}
}
複製代碼
Android 程序經常要處理UI,若是本應該當即更新的UI,卻延遲了幾十甚至上百毫秒,勢必形成用戶體驗降低。因此在開發的時候要特別注意,儘可能不要在UI線程處理後臺任務,而在UI線程中的任務要儘可能及時處理,特別是要避免已經在UI線程中了,還經過Handler執行任務。開發