handler是什麼?
handler是android給我們提供用來更新UI的一套機制,也是一套消息處理機制,我們可以發送消息,也可以通過它處理消息。
android中更新ui四種方式:
1、runonui
只能在Activity中使用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
updateUI();
}
}).start();
}
private void updateUI() {
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("run on UI thread");
}
});
}
2、view.post(runable)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
viewUI();
}
}).start();
}
private void viewUI() {
textView.post(new Runnable() {
@Override
public void run() {
textView.setText("view update UI");
}
});
}
3、handler.post()
private Handler mhandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
new Thread(new Runnable() {
@Override
public void run() {
mhandler.post(new Runnable() {
@Override
public void run() {
textView.setText("update thread");
}
});
}
}).start();
}
4、handler.sendmessage
private Handler mhandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
textView.setText(msg.arg1 + msg.arg2 + msg.obj.toString());
}
};
private TextView textView;
class Person {
private String name;
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
Message msg = new Message();
msg.arg1 = 1;
msg.arg2 = 2;
msg.obj = new Person("Gomez");
mhandler.sendMessage(msg);
//第二種發送消息方法
// msg = mhandler.obtainMessage();
// msg.sendToTarget();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
子線程創建Handler
private Handler mhandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println("UIThread:" + Thread.currentThread());
}
};
private TextView textView;
private MyThread myThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
myThread = new MyThread();
myThread.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
myThread.handler.sendEmptyMessage(1);
mhandler.sendEmptyMessage(1);
}
class MyThread extends Thread {
Handler handler;
@Override
public void run() {
super.run();
//初始化looper
Looper.prepare();
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println("currentThread:" + Thread.currentThread());
}
};
//循環讀取消息
Looper.loop();
}
}
}
運行效果:
HandlerThread
- HandlerThread本質上是一個線程類,它繼承了Thread;
- HandlerThread有自己的內部Looper對象,可以進行looper循環;
- 通過獲取HandlerThread的looper對象傳遞給Handler對象,可以在handleMessage方法中執行異步任務。
- 創建HandlerThread後必須先調用HandlerThread.start()方法,Thread會先調用run方法,創建Looper對象。
通過HandlerThread可以避免自定義線程中很多空指針問題,如上例如果不在主線程中加入延時,那個我們拿到的子線程的handler是爲空的。
private HandlerThread handlerThread;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handlerThread = new HandlerThread("handler thread");
handlerThread.start();
handler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println("current thread" + Thread.currentThread());
}
};
handler.sendEmptyMessage(1);
}
在HandlerThread拿到的Looper都是安全的,在內部已經處理多線程同步;
這樣所有handleMessage都是在子線程中執行,用HandlerThread模擬一些異步任務,主線程給子線發送消息,子線程執行一些耗時操作,比如一些下載圖片,訪問服務器都可以這樣去執行。