Android WeakReference的应用:自定义Handler : WeakHandler

背景:

    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 extends Handler{
        private final WeakReference host;

        public WeakHandler(T host) {
            this.host = new WeakReference(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 extends Handler{
    private WeakReference host;

    public WeakHandler(T host){
        this.host = new WeakReference(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的实现方式更完善,推荐使用第二种。

《完》

 

 

 

你可能感兴趣的:(Android基础)