Handler與線程的關係

 在一個Android 程序開始運行的時候,會單獨啓動一個Process。默認的狀況下,全部這個程序中的Activity或者Service(Service和 Activity只是Android提供的Components中的兩種,除此以外還有Content Provider和Broadcast Receiver)都會跑在這個Process。android

        一個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.ide

       意思是,沒法在子線程中更新UI。爲此,咱們須要經過Handler物件,通知主線程Ui Thread來更新界面。函數

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

      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);隊列

更新UI只能是主線程的工做,子線程更新UI是線程不安全的,因此android裏非主線程操做主UI就會報錯。
子線程可能會有多個,多個同時操做一個控件可能會有麻煩發生,因此android就限定了只有主線程能夠操做UI。子線程想操做UI,能夠,你告訴我(主線程),我來更新。

2.1、Handler的定義:
          主要接受子線程發送的數據, 並用此數據配合主線程更新UI.
          解釋: 當應用程序啓動時,Android首先會開啓一個主線程 (也就是UI線程) , 主線程爲管理界面中的UI控件,進行事件分發,
 好比說, 你要是點擊一個 Button, Android會分發事件到Button上,來響應你的操做。 
 若是此時須要一個耗時的操做,例如: 聯網讀取數據,或者讀取本地較大的一個文件的時候,你不能把這些操做放在主線程中,
 若是你放在主線程中的話,界面會出現假死現象, 若是5秒鐘尚未完成的話,會收到Android系統的一個錯誤提示  "強制關閉". 
 這個時候咱們須要把這些耗時的操做,放在一個子線程中,由於子線程涉及到UI更新,Android主線程是線程不安全的,也就是說,
 更新UI只能在主線程中更新,子線程中操做是危險的. 這個時候,Handler就出現了來解決這個複雜的問題,因爲Handler運行在主線程中(UI線程中),
 它與子線程能夠經過Message對象來傳遞數據,這個時候,Handler就承擔着接受子線程傳過來的(子線程用sedMessage()方法傳弟)Message對象,(裏面包含數據)  ,
 把這些消息放入主線程隊列中,配合主線程進行更新UI。


2、Handler一些特色
        handler能夠分發Message對象和Runnable對象到主線程中, 每一個Handler實例,都會綁定到建立他的線程中(通常是位於主線程),
        它有兩個做用: (1):  安排消息或Runnable 在某個主線程中某個地方執行, (2)安排一個動做在不一樣的線程中執行

總結:new出一個hander的監聽器,並不表明建立了一個新的線程。它是主線程的一個listener,用來接收子線程發出的更新UI的消息。

相關文章
相關標籤/搜索