解析Android中的main線程與子線程

來源:互聯網
上載者:User

在一個Android
程式開始啟動並執行時候,會單獨啟動一個Process。預設的情況下,所有這個程式中的Activity或者Service(Service和
Activity只是Android提供的Components中的兩種,除此之外還有Content Provider和Broadcast
Receiver)都會跑在這個Process。

        一個Android 程式預設情況下也只有一個Process,但一個Process下卻可以有許多個Thread。
  
      
在這麼多Thread當中,有一個Thread,我們稱之為UI Thread。UI
Thread在Android程式啟動並執行時候就被建立,是一個Process當中的主線程Main
Thread,主要是負責控制UI介面的顯示、更新和控制項互動。在Android程式建立之初,一個Process呈現的是單執行緒模式,所有的任務都在一
個線程中運行。因此,我們認為,UI
Thread所執行的每一個函數,所花費的時間都應該是越短越好。而其他比較費時的工作(訪問網路,下載資料,查詢資料庫等),都應該交由子線程去執行,
以免阻塞主線程。

        那麼,UI Thread如何和其他Thread一起工作呢?常用方法是:

        誕生一個主線程的Handler物件,當做Listener去讓子線程能將訊息Push到主線程的Message Quene裡,以便觸發主線程的handlerMessage()函數,讓主線程知道子線程的狀態,並在主線程更新UI。

       例如,在子線程的狀態發生變化時,我們需要更新UI。如果在子線程中直接更新UI,通常會拋出下面的異常:
  
       
11-07 13:33:04.393:
ERROR/JavaBinder(1029):android.view.ViewRoot$CalledFromWrongThreadException:Only
the original thread that created a view hierarchy can touch its views.

       意思是,無法在子線程中更新UI。為此,我們需要通過Handler物件,通知主線程Ui Thread來更新介面。

        如下,首先建立一個Handler,來監聽Message的事件:

       private final int UPDATE_UI = 1;
       private Handler mHandler = new MainHandler();
    
      private class MainHandler extends Handler {
         @Override
             public void handleMessage(Message msg) {
             switch (msg.what) {
                 case UPDATE_UI: {
                Log.i("TTSDeamon", "UPDATE_UI");
                showTextView.setText(editText.getText().toString());
                ShowAnimation();
                     break;
                 }
                 default:
                     break;
             }
         }
       }

     或者

      private Handler mHandler = new Handler(){
         @Override
             public void handleMessage(Message msg) {
             switch (msg.what) {
                 case UPDATE_UI: {
                Log.i("TTSDeamon", "UPDATE_UI");
                showTextView.setText(editText.getText().toString());
                ShowAnimation();
                     break;
                 }
                 default:
                     break;
             }
          }
      }

       當子線程的狀態發生變化,則在子線程中發出Message,通知更新UI。

       mHandler.sendEmptyMessageDelayed(UPDATE_UI, 0);

   
      在我們的程式中,很多Callback方法有時候並不是運行在主線程當中的,所以如果在Callback方法中更新UI失敗,也可以採用上面的方法。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.