在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();
}
}