0x01 Handler的作用
Handler主要用于在工作线程中更新主线程的UI操作。
0x02 实现方式
Handler的实现方式有两种,一种是通过Handler.sendMessage()、另外一种是通过Handler.post()。事实上两种方式的本质是一样的。
0x03 简单使用
1. Handler.sendMessage()
// 在主线程中创建Handler处理message并进行UI操作
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 1:
tv.setText("obtain message 1");
break;
case 2:
tv.setText("obtain message 2");
break;
}
}
};
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 传递主线程Handler
Sendmsg s = new Sendmsg(mHandler,1);
new Thread(s).start();
}
});
}
// 创建线程类并发送消息,控制UI
class Sendmsg implements Runnable {
private Handler handler;
private int msg;
public Sendmsg(Handler mHandler,int msg){
this.handler = mHandler;
this.msg = msg;
}
@Override
public void run() {
this.handler.obtainMessage(this.msg).sendToTarget();
}
}
思想就是在主线程中创建一个handler,并重写handlerMessage(),之后传递给子线程类中,子线程通过发消息从而控制handler进行UI等相关操作。
2. Handler.post()
// 在主线程中创建Handler
mHandler = new Handler();
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Postmessage(mHandler).send();
}
});
}
class Postmessage {
private Handler handler;
Postmessage(Handler handler){
this.handler = handler;
}
public void send(){
this.handler.post(new Runnable() {
@Override
public void run() {
tv.setText("Post message");
}
});
}
}
这两种方式都需要获取tv变量,因此在另外的线程中可能还需要传递该变量,此时可以使用弱引用weakreference,可以防止内存泄漏。
0x03 小结
还有一个非常重要的地方没有说,Handler是既然是一个处理机制,能够不断的监听接受并处理消息,因此他必然需要一个循环体。事实上Handler需要绑定到一个Looper上,从而完成消息的循环获取与移除。实例中默认都是实用的主线程中的Looper。