背景:
WeakReference(弱引用)作用:防止被强引用的对象的内存不被释放。
android开发中使用Handler出现的情况,比如在Activity内部new一个Handler:
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
//更新UI
break;
}
}
};
Hanler的机制是调用handler.sendMessage()方法时,先由MessageQueue收入,等待Looper.loop()从消息队列中一个一个取出消息执行,此时如果调用执行有一个时间延迟,在延迟的过程中调用了activity的finish()结束activity,但此时message由Loop持有,而message又持有Handler,Handler持有Activty,这就导致该activity的所有资源在这段延迟时间之前将不能被释放,此时就导致内存泄漏。
解决办法:
导致上述情况的罪魁祸首,就是Handler对Activity对象的持有导致Activity不被GC回收,而WeakReference就很好的解决了这个问题,此时被持有Activity对象在下一次GC执行时,将会被系统回收。
我们需要一个具有类似功能的Handler,这个Handler不会强制持有它的宿主对象Activity,接下来咱们进入主题WeakHandler。
WeakHandler
方式1.内部类声明
WeakHandler myHandler = new WeakHandler(this);
void method(){
myHandler.sendEmptyMessage(1);
}
static class WeakHandler<T> extends Handler{
private final WeakReference<T> host;
public WeakHandler(T host) {
this.host = new WeakReference<T>(host);
}
@Override
public void handleMessage(Message msg) {
//表示持有对象已经被GC回收
if(host.get() == null) return;
switch (msg.what){
case 1:
//do something
break;
default:
break;
}
}
}
这种方式虽然可以实现,适合使用Handler使用次数少的项目,如果一个项目里边有好几个甚至几十个类需要引用Handler,就不是很理想了。
接下来我们介绍第二种WeakHandler的实现方式。
2.外部类声明
先声明一个外部类:
public abstract class WeakHandler<T> extends Handler{
private WeakReference<T> host;
public WeakHandler(T host){
this.host = new WeakReference<T>(host);
}
@Override
public final void handleMessage(Message msg) {
if(host.get() == null){
handleMessageWhenNotServive(msg);
}else{
handleMessageWhenServive(msg, host.get());
}
}
//当引用对象存在(未被GC回收)时,调用此方法
public abstract void handleMessageWhenServive(Message msg, T host);
//当引用对象不存在(已被GC回收)时,调用此方法,非必须重写
public void handleMessageWhenNotServive(Message msg){}
}
在需要使用Handler的类中创建一个类继承该父类并调用:
MyWeakHandler myWeakHandler = new MyWeakHandler(this);
void method2(){
myWeakHandler.sendEmptyMessage(1);
}
private static class MyWeakHandler extends main.wdmixdemo.com.wdmixdemo.weakreference.WeakHandler{
public MyWeakHandler(Object host) {
super(host);
}
@Override
public void handleMessageWhenServive(Message msg, Object host) {
switch (msg.what){
case 1:
//do something
break;
default:
break;
}
}
//unnecessary
@Override
public void handleMessageWhenNotServive(Message msg) {
super.handleMessageWhenNotServive(msg);
}
}
总结
以上两种创建WeakHandler的方式都是可行的,相对而言1的代码比2简洁,但2的实现方式更完善,推荐使用第二种。
《完》