重谈Handler的内存泄漏

Handler 的内存泄漏问题

多线程操作中,handler会使用的非常多,但是每次使用handler你有没有考虑内存泄漏的问题。

如果你使用handler进行操作时,你会发现出现以下提示
This Handler class should be static or leaks might oc多线程是什么意思cur (anonymous an多线程和多进程的区别droid.os.Handler)这样的提示。翻译:
由于此Handler被声明为内部类,因此可能会阻止外部类被垃圾回收。 如果Handler使用Looper或MessageQueue作为主多线程面试题线消息队列的作用程以外的线程,则没有问题。 如果Handler正在使用主线程的Looper或MessageQueue,则需要修复Handler声android的drawable类明,如下所示:将Handler声明为静态类; 在外部类中,实例化外部类的WeakReference,并在实例化Handler时将此对象传消息队列面试题递给Handler; 使用WeakReference对象对外部类的多线程渲染成员java面试题进行所有引用。android的drawable类

警告原消息队列的使用场景因:handler没有设置为静态类,声明内多线程是什么意思部类可能会阻止被GC回收,从而导致内多线程是什么意思存泄漏

那么为什么会造成内存泄漏呢。
首先来说下什么是内存泄漏
内存泄漏实例化(Memory Leak):指的是程序已经动态分配的堆内存类的实例化由于某种原因程序未释放或者无法释放,造成系统资源浪费,会造成程序运行缓慢甚至系统崩溃等严重后果。
问题代多线程编程码:

public class MainActivity extends AppCompatActivity {
    private Handler mHandler = new Handler();
    private TextView mTextView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.tv);
        //模拟内存泄漏
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mTextView.setText("yiyi");
            }
        }, 1000);
    }
}

内存泄漏原因

从上面问多线程题代码,可以看出这里通过内部类方式创建handler,而在java中,非静态内部类会持有多线程下载是什么意思外部类的引用,这里的postDelayed是一个延迟处理消息,将一个handler装入到message中,将消息放进消息队列messageQueueLooper进行取消息进行处理。如果此时activity要退出了,想要调用**destroy**销毁,但是此时Looper正在处理消息,**Looper**的生命周期明显比activity长,这将实例化对象使得activity无法被**GC**回收,最终造成内存泄漏。并且此时handler还持有activity的引用,也是造成内存泄漏的多线程下载一个原因(不是根本原因)。

但是我觉得真正handler造java面试题成内存泄多线程面试题漏的根本原因是生命周期比actiandroid手机vity长,比如TextView也是内部类创建的,那么它怎么Java没有造成消息队列的使用场景内存泄漏,它也持有外部类Activity的引用,根本原因是它的生命周期比Activity短,Acti消息队列原理vity销毁时候,它可以被GC回收

总结

当haandroid是什么系统n多线程应用场景例子dler有没javascript百炼成仙有处理的消息或者正在处理消息,此时Handler的生命周期明显比Activity长,GC持有Activity与handler两者的引用,导致Activity无多线程应用场景例子法被GC回收,造成内存泄漏。而handler是不是内部类,并不是造成内java怎么读存泄android是什么系统漏的根本原因。

解决方案

静态内部类+弱Java引用

将Hanandroid平板电脑价格dler的子类设置成 静态内部类,并实例化且可加上 使用WeakReference弱引用持有Activity实例

原因:实例化对象弱引用的对象拥有短暂的生命周期。而垃圾回收器不管内存是否充足都会回收弱引用对象。

public class HandlerActivity extends AppCompatActivity  {
    private static class MyHandler extends Handler {
    private final WeakReference<HandlerActivity> mActivity;
    public MyHandler(HandlerActivity activity) {
        mActivity = new WeakReference<HandlerActivity>(activity);
    }
    @Override
    public void handleMessage(Message msg) {
        HandlerActivity activity = mActivity.get();
        if (activity != null) {
        }
    }
    private final MyHandler mHandler = new MyHandler(this);
    private static final Runnable mRunnable = new Runnable() {
        @Override
        public void run() { }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mHandler.postDelayed(mRunnable, 1000 * 60 * 1);
        finish();
    }
}

Activity生命周期结束时,清空消息队列
只需在Activity的onDestroy()方法中调用mHandler.removeCallbacksAndMessages(null);就行了。

@Override
protected void onDestroy() {
    super.onDestroy();
    if(handler!=null){
        handler.removeCallbacksAndMessages(null);
        handler = null;
    }
}

发表评论

提供最优质的资源集合

立即查看 了解详情