站內搜尋

2011/2/25

Android Tips 開發小技巧 - Handler.post

剛接觸 Android 程式開發的人,往往容易寫出會讓整個程式停下來的 Code,
而大多數的原因其實都很單純,就只是因為你放了loading太重的程式碼在 Main thread 中,
我們可以用很簡單的方法來解決這個問題。


在 Android 的官網有很明確的定義 (通常有些特別的 API 也會在 references 中注明),
和UI有關的任何更新及操作,都需要在UI thread完成,一般就是 Main thread。

然而當 Main thread 被某一段程式碼給綁架(花許多時間處理一段程式 ex: 很大圈的 loop)之後,你的 UI 就自然而然的無法進行更新重畫的動作。
所以,假設你的程式需要大量的計算,請習慣開一個 Thread 去處理它。

但這時後卻又會碰到一個問題。
那假設我的程式碼需要大量時間處理,但處理完之後又要控制 UI 產生對應的動作呢?
(比如改變文字等..)

這時後你就可以使用 Handler 來處理這個小問題,
將UI的操作利用Handler物件包回Main thread處理。

對這東西太陌生的人,可以將 Handler 想像成是 MSFT的 Message 機制。
(但其實還是差距滿大的,在 Android 中 Looper 可以算是一個 Message queue,而 Handler 則是用來使用某一個 Looper 的介面而以。但...打個比方嘛..別太計較...)

因此,就可以用 Handler 將自己想要處理的訊息塞回 main thread 的 Looper,請它幫我們處理事情。

簡單講,就是你可以在其他的thread利用sendMessage來叫main thread做事情,最重要的就是UI相關的處理。

但有些時後你需要進行的動作很單純,除了message這一類的處理,Handler還提供了另一個即時的處理方式,叫 Handler.post。

它提供了一個method,讓你將某一個 runable 的 object 塞進Message queue,然後叫 handler 所屬的 thread 執行它。

也許大家看到這裡會有疑問,不是說要讓 main thread 來處理嗎?
沒錯,Android 的設計裡面,假設你的 handler 在生成的時後沒有特別指定,則它會自動和你現在正在 run 的 thread 綁在一起,所以呢,你常常會看見 new Handler() 的地方都會被放在activity 物件的成員變數的宣告式,或者是 activity 的 onXXXX() 裡面,就是為了要將這個 handler 和 main thread 綁在一起。

下面是簡單的code。
Handler mHandler = new Handler();
       .
       ....
       .
mHandler.post(new Runnable() {
    public void run()
    {
        TextView textBox= (TextView)getViewById(R.id.textbox);
        textBox.setText(R.string.login_failed);
    }
});
如此,在 Main thread 有空的時後,就會將這段程式碼跑起來,
而就達到利用 Main thread 來更新 UI 的要求了。

總合上面的東西,簡單講,假設你的程式很肥很大要處理的事情很多,
你應該盡可能不要佔用Main thread的時間,讓和UI無關的處理可以在其他thread做,
而讓main thread專心做他原來的工作,這樣也許可以讓整體反應好一點

Reference
http://www.cnblogs.com/duguguiyu/archive/2008/01/24/1050813.html
http://developer.android.com/reference/android/os/Handler.html#post(java.lang.Runnable)
http://developer.android.com/guide/topics/fundamentals.html#procthread

熱門文章