在一個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。ide
例如,在子線程的狀態發生變化時,咱們須要更新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;
}
}
}get
或者it
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;
}
}
}io
當子線程的狀態發生變化,則在子線程中發出Message,通知更新UI。
mHandler.sendEmptyMessageDelayed(UPDATE_UI, 0);
在咱們的程序中,不少Callback方法有時候並非運行在主線程當中的,因此若是在Callback方法中更新UI失敗,也能夠採用上面的方法。