[原] Android performClick無效,UI執行緒理解

雨知發表於2013-11-21

原因

開發過程中遇到button.performClick()無效,原因是View.performClick()需要再UI執行緒中呼叫才會有效執行。

響應系統呼叫的方法(比如報告使用者動作的onKeyDown()或一個生命週期回撥方法)永遠在介面執行緒中程式,所以onCreate裡面呼叫button的performClick沒問題,
而通過code直接呼叫相當於是程式碼執行,並不會觸發android的UI執行緒。

什麼是UI執行緒,以下來自官網翻譯

當一個應用被啟動,系統建立一個執行執行緒,叫做"main"。這個執行緒是十分重要的,因為它主管向使用者介面控制元件派發事件。其中包含繪圖事件。它也是你的應用與介面工具包(android.widget和 android.view包中的元件)互動的地方。於是main執行緒也被稱為介面執行緒。

系統不會為每個元件的例項分別建立執行緒。所有執行於一個程式的元件都在介面執行緒中被例項化,並且系統對每個元件的呼叫都在這個執行緒中派發。因此,響應系統呼叫的方法(比如報告使用者動作的onKeyDown()或一個生命週期回撥方法)永遠在介面執行緒中程式。

例如,當使用者觸控螢幕上的一個按鈕時,你的應用的介面執行緒把觸控事件派發給控制元件,然後控制元件設定它的按下狀態再向事件佇列發出一個自己介面變得無效的請求,介面執行緒從佇列中取出這個請求並通知這個控制元件重繪它自己。

http://wiki.eoeandroid.com/Processes_and_Threads

解決方法,最簡單的方式

View.post(new Runnable(){
    @Override
    public void run() {
        button.performClick();
    }
});

View.post(Runnable)方法。在post(Runnable action)方法裡,View獲得當前執行緒(即UI執行緒)的Handler,然後將action物件post到Handler裡。在Handler裡,它將傳遞過來的action物件包裝成一個Message(Message的callback為action),然後將其投入UI執行緒的訊息迴圈中。在Handler再次處理該Message時,有一條分支(未解釋的那條)就是為它所設,直接呼叫runnable的run方法。而此時,已經路由到UI執行緒裡,因此,我們可以毫無顧慮的來更新UI。

Activity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        button.performClick();
    }
});

Activity.runOnUiThread(Runnable)把更新ui的程式碼建立在Runnable中,然後在需要更新ui時,把這個Runnable物件傳給Activity.runOnUiThread(Runnable)。 這樣Runnable對像就能在ui程式中被呼叫。如果當前執行緒是UI執行緒,那麼行動是立即執行。如果當前執行緒不是UI執行緒,操作是釋出到事件佇列的UI執行緒

android提供了幾種常用的方式,用於實現後臺執行緒與UI執行緒的互動

  • 1. handler
  • 2. Activity.runOnUIThread(Runnable)
  • 3. View.Post(Runnable)
  • 4. View.PostDelayed(Runnabe,long)
  • 5. AsyncTask

相關文章