[原] Android performClick無效,UI線程理解


原因

開發過程中遇到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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM