【问题标题】:Will handler inside a method leak memory?方法内的处理程序会泄漏内存吗?
【发布时间】:2014-03-04 04:01:42
【问题描述】:

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

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

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");
}

【问题讨论】:

    标签: android memory-leaks handler


    【解决方案1】:

    在特定条件下可以。如果传递的可运行对象是匿名类或内部类,如您的示例所示,它包含对“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);
    }
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 那么“textView”和activity在消息被处理之前不能被gc?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      • 2012-11-15
      • 2011-01-13
      • 2011-09-16
      • 2012-07-01
      • 2012-11-02
      • 1970-01-01
      相关资源
      最近更新 更多