標籤:
在android開發過程中,耗時操作我們會放在子線程中去執行,而更新UI是要主線程(也叫做:UI線程)來更新的,自然會遇到如何更新主線程UI的問題。如果在主線程之外的線程中直接更新頁面顯示常會報錯。拋出異常:android.view.ViewRoot.CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
為什麼要有handler機制?
handler的作用:與其他線程協同工作,接收其他線程的訊息並通過接收到的訊息更新主UI線程的內容。
handler的原理:
andriod提供了 Handler 和 Looper 來滿足線程間的通訊。Handler 先進先出原則。Looper類用來管理特定線程內對象之間的訊息交換(Message Exchange)。
1)Looper: 一個線程可以產生一個Looper對象,由它來管理此線程裡的Message Queue(訊息佇列)。 whille死迴圈
2)Handler: 你可以構造Handler對象來與Looper溝通,以便push新訊息到Message Queue裡;或者接收Looper從Message Queue取出)所送來的訊息。
3)Message Queue(訊息佇列):用來存放線程放入的訊息。
4)線程:UI thread 通常就是main thread,而Android啟動程式時會替它建立一個Message Queue。
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
public class MainActivity extends Activity {
protected static final int MSG_ONE = 1;
protected static final int MSG_TWO = 2;
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_ONE:
// 執行1的操作
break;
case MSG_TWO:
// 執行2的操作
break;
};
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 耗時操作要在子線程中操作
new Thread() {
public void run() {
Message message = Message.obtain(); //擷取訊息的載體
if (condition) {
message.what = MSG_ONE;
} else {
message.what = MSG_TWO;
}
handler.sendMessage(message);
};
}.start();
}
}
package com.itheima.zhbj;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 耗時操作要在子線程中操作
new Thread() {
public void run() {
//執行耗時操作
//更新主線程UI
runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
};
}.start();
}
}
Android更新主線程UI的兩種方式handler與runOnUiThread()