Android謹慎使用Handler

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執行任務。開發

相關文章
相關標籤/搜索