在日常的开发过程中,Handler还是有着一定的出场率,那么Handler是怎么来帮助我们实现线程间的通信的呢?
首先来看一段Handler的基本使用代码
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle bundle = msg.getData();
textView.setText(bundle.getString("key"));
}
};
ps:这段代码在一定的情况下会引起内存泄漏,原因是Java的非静态内部类会持有外部类的引用,实际开发中可能是Activity或者Fragment的引用,当他们以及销毁,但是handler还持有其引用,在垃圾回收的时候就不会被回收,从而引发内存泄漏。
new Thread(() -> {
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putString("key", "value");
message.setData(bundle);
handler.sendMessage(message);
}).run();
子线程中向主线程发了一条消息,然后在主线程中更新UI,使用起来很简单,但是Handler在内部为我们做了很多工作,接下来一步步的看Handler究竟是怎么为我们实现具体的功能的。
我们从子线程开始,也就是消息需要发送的地方,这里初始化了一个Message对象,那先点进去Message类
public final class Message implements Parcelable {
//..
Handler target;
//..
}
Message实现了Parcelable接口,为了更方便的传递数据
接下来声明了一些成员变量,于我们常常写的Bean对象思路一致
以及一个Handler的成员变量,这里先混个眼熟,后面会用到
接下来看到了obtain的一系列重载方法
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}
因为Handler使用频率较高,所以Android为它设计了回收机制,通过一个全局实例,来避免多次创建Message
看到这里的源码,我们就可以修改源程序为
new Thread(() -> {
Message messag