android 之handler浅谈

作者: 石头_起航 | 来源:发表于2018-06-08 16:33 被阅读42次

昨天虽然是简单的了解使用方法但是在使用中 不知道有没有人会遇到问题 ,内存泄漏的问题,当然你像我那样写的话 as也会给你提醒,背景颜色不同,并且光标移动到代码出会出现

Since this Handler is declared as an inner class, it may prevent the outer class from being garbage collected. If the Handler is using a Looper or MessageQueue for a thread other than the main thread, then there is no issue. If the Handler is using the Looper or MessageQueue of the main thread, you need to fix your Handler declaration, as follows: Declare the Handler as a static class; In the outer class, instantiate a WeakReference to the outer class and pass this object to your Handler when you instantiate the Handler; Make all references to members of the outer class using the WeakReference object.

具体的提醒是这样的,建议是使用弱引用,因为在非静态内部类会持有隐式的外部类引用,这样就会导致 如果 外部的activity不被使用了 原本应该被回收掉,但是由于内部非静态类的引用,内部非静态类如果还在被使用,所以外部被引用的类就不能被回收掉,从而会导致内存泄漏。解决方法是 Make all references to members of the outer class using the WeakReference object.(使用弱引用对象对外部类成员进行所有引用。)

如果您不相信可以测试一下 可以用内存泄漏检测工具 (网上一大堆的检测工具),你也可以像我一样

    handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            EventBus.getDefault().post(new String("ssdsdsdsds"));
        }
    };
    Message message = Message.obtain();
    handler.sendMessageDelayed(message, 1000 * 30);
    startActivity(new Intent(MainActivity.this, Main2Activity.class));
    finish();

设置消息延迟30秒发送,并且引入eventbus 使用它来发送消息在Main2Activity来进行接受这个消息,并且来进行打印,这样你就会发现 这条消息被打印了,也就是说 finish();了但是并没有被回收掉。解决方法
private static class MyHandler extends Handler {
private WeakReference<MainActivity> mMainActivity;//弱引用

    public MyHandler(MainActivity mainActivity) {
        mMainActivity = new WeakReference<MainActivity>(mainActivity);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        EventBus.getDefault().post(new String("ssdsdsdsds"));
    }
}

    handler = new MyHandler(this);
    Message message = Message.obtain();
    handler.sendMessageDelayed(message, 1000 * 30);
    startActivity(new Intent(MainActivity.this, Main2Activity.class));
    finish();

做了弱引用测试发现消息还是会被发出。
在 onDestroy()添加以下方法消息就不会被发出了,
handler.removeCallbacksAndMessages(null);//移除消息队列
当然这样检测存在很多问题,但是个人认为消息既然能被发出,就应该能够证明页面页面还没有被销毁,消息队列还存在,不发eventbus 直接打Log日志也会记录,也就是说没有被及时回收掉(onDestroy()已经执行),handler.removeCallbacksAndMessages(null);//移除消息队列其实就是移除消息队列,无论怎么引用这个方法执行后 消息队列就会被清空从而不会接受到消息。

这样检测的方法我认为存在很多问题,因为java垃圾回收机制是没有办法人为控制的 这样就会导致垃圾可能不会被及时的回收,资源可能没有别及时释放,所以就有可能会出现以上情况,欢迎留言 共同讨论。欢迎纠正错误。总之就是在页面onDestroy的时候把能释放的资源全释放掉。

使用as自带内存检测工具 发现即使是空白页面反复打开 内存也会持续上升,使用了弱引用后内存相对的来说会比之前不用软饮用稍微低一点(测试机 魅族) 后来查阅资料明白 android activity虽然执行了finish 也执行了onDestroy但是并没有内存并没有被立即回收,手动执行GC的时候就会发现内存泄漏和不内泄漏的差别

相关文章

网友评论

    本文标题:android 之handler浅谈

    本文链接:https://www.haomeiwen.com/subject/wjeasftx.html