Handler主要用于异步消息处理:Handler发送消息到MessageQueue,Looper循环从MessageQueue中拿出消息Message,然后交给Handler处理。
一、Handler使用
1.1.创建handler的两种方式
方式一:
private Handler handler1 = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
return false;
}
});
方式二:
private Handler handler2= new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
}
};
1.2.发送消息
在子线程中发送消息到UI线程
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what=3;
message.obj="Hello";
handler1.sendMessage(message);
//延时发送消息
//handler1.sendMessageDelayed(message,3000);
}
});
1.3.在UI线程处理消息
在handler中收到消息,做相应的处理,如更新UI
注意:消息以链表的结构存放在MessageQueue,时间优先队列
二、handler的内存泄漏问题
handler必须手动的去销毁,否则activity的销毁并不能讲handler销毁,这样会造成Looper.loop()的循环,从而内存泄漏。
2.1.解决内存泄漏的方法一
public void test(){
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what=3;
//延时发送消息
handler1.sendMessageDelayed(message,3000);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
handler1.removeMessages(3);
}
2.2.解决内存泄漏的方法二
public void test(){
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what=3;
SystemClock.sleep(3000);
if (handler1!=null) handler1.sendMessage(message);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
handler1.removeMessages(3);
handler1=null;
}
三、为什么不能在子线程创建handler
应用在启动的时候,会启动ActivityThread,ActivityThread中有一个main方法,会调用Looper.prepareMainLooper();获取一个Looper对象,而我们在子线程获取的Looper是在应用启动时主线程创建的,所以在子线程创建的Handler是拿不到Looper的,这个时候就回抛出异常。