在方法内使用handler会造成内存泄漏吗?

3

我知道在一个类中声明的处理程序可能会泄漏内存,因为它持有对其外部类的引用。在这种情况下,我们应该使用具有弱引用的静态嵌套类。

但是,如果在方法中声明处理程序,该怎么办?我遇到了下面的情况,不确定它是否是正确的实现。请问有人能够解释一下或者给我一个提示吗?我甚至不知道该搜索什么。

private void methodA(){
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {            
        @Override
            public void run() {
            methodB();
        }
    }, 10*1000);

private void methodB(){
    //textView holds a reference to a activity
    textView.setText("hello");
}
2个回答

2
在某些情况下,它确实可以。如果传递的可运行对象是匿名或内部类(就像您的示例一样),则它会隐式持有对“this”的引用,并防止在将可运行对象从队列中处理之前对“this”进行垃圾回收(因此,如果您的方法从未运行,例如如果您的处理程序线程在不清除队列的情况下停止,则会发生泄漏)。
如果您担心可能会出现内存泄漏或者对象被挂起太久的情况,那么您需要将可运行对象设置为静态类,并在构造函数中初始化一个弱引用,例如:
private static MyRunnable implements Runnable
{
    private final WeakReference<MyClass> myClass_weakRef;

    public MyRunnable(MyClass myClassInstance)
    {
        myClass_weakRef = new WeakReference(myClassInstance);
    }

    @Override
    public void run()
    {
        MyClass myClass = myClass_weakRef.get();
        if(myClass != null)
            myClass.methodB();
    }
}

private void MethodA()
{
    Handler handler = new Handler();
    handler.postDelayed(new MyRunnable(this), 10*1000);
}

0
在你的方法中创建一个Handler并不是一个特殊情况。它属于相同的情况,即你发布的Message将会一直存在于消息队列中,直到被处理。

那么在消息被处理之前,“textView”和活动不能被垃圾回收吗? - David Lam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接