首页 文章

此Handler类应该是静态的,否则可能会发生泄漏:final Handler

提问于
浏览
5

在下面的代码中Eclipse生成警告“此Handler类应该是静态的,否则可能会发生泄漏” .

public class MyActivity extends Activity implements Runnable
 {
   final Handler handler = new Handler()
    {
      @Override
      public void handleMessage( Message message)
       {
         String sResult = (String) message.obj;
         if( (sResult != null) && (sResult != ""))
           {
             MyNonStatic = (TableLayout) findViewById( R.id.tableLayout); // any non-static method
           }
         return;
       }
    };


   public void run()
    {
      final Message message = handler.obtainMessage( 1, MyFunction( context));
      handler.sendMessage( message);
    }

   public String MyFunction( Context context)
    {
      return "MyNewString";
    }
  }

我在网站上审查了很多主题,但没有得到解决方案 . 请帮帮我这个代码?

添加:我需要在handleMessage()中调用非静态方法(例如findViewById())!

3 回答

  • 2

    下面是一个使用弱引用和静态处理程序类来解决Lint文档中建议的问题的示例:

    public class MyClass{
    
      //static inner class doesn't hold an implicit reference to the outer class
      private static class MyHandler extends Handler {
        //Using a weak reference means you won't prevent garbage collection
        private final WeakReference<MyClass> myClassWeakReference; 
    
        public MyHandler(MyClass myClassInstance) {
          myClassWeakReference = new WeakReference<MyClass>(myClassInstance);
        }
    
        @Override
        public void handleMessage(Message msg) {
          MyClass myClass = myClassWeakReference.get();
          if (myClass != null) {
            ...do work here...
          }
        }
      }
    
      private final MyHandler mHandler = new MyHandler(this);
    
      public void getHandler() {
        return new MyHandler(this);
      }
    }
    
  • 2

    handler - 处理程序标识应发生回调的线程 . 如果为null,则回调将从进程的线程池发生 .

    想象一下情况 . 一些活动调用 PendingIntent.send(...) 并放置 non-static inner subclass of Handler . 然后活动被摧毁 . But inner class lives .

    内部类仍然存在被破坏活动的链接,它不能被垃圾收集 .

    因此你需要让它变得静止 .

    资料来源:Handlers and memory leaks in Android

  • 5

    Android lint checks

    HandlerLeak
    -----------
    Summary: Ensures that Handler classes do not hold on to a reference to an
    outer class
    
    Priority: 4 / 10
    Severity: Warning
    Category: Performance
    
    In Android, Handler classes should be static or leaks might occur. Messages
    enqueued on the application thread's MessageQueue also retain their target
    Handler. If the Handler is an inner class, its outer class will be retained as
    well. To avoid leaking the outer class, declare the Handler as a static nested
    class with a WeakReference to its outer class.
    

    警告的第一部分是因为 final Handler handler = new Handler() 创建了一个匿名内部类 . 内部类不能以独立方式创建,您始终需要外部实例 . 记住如何在Java中创建它 OuterClass.InnerClass innerObject = outerObject.new InnerClass(); . 每个内部类对象还必须保持对外部对象 Outer.this 的引用以访问外部成员 .

    第二部分是 final Message message = handler.obtainMessage( 1, MyFunction( context)); 有一个内部处理程序类的句柄(它有一个外部Activity类的处理程序) . 如果此消息的存在时间足够长,则无法对您的活动进行垃圾回收 .

    什么可以阻止您的邮件被处理?不幸的是,lint工具无法解决这个问题,因此它始终会警告您可能存在内存泄漏 . 如果您确定自己在做什么,可以通过various methods来禁止这些消息 .

    对于你的情况,使 Activity a Runnable 看起来不是一个好主意,但无论如何可能你应该使用Handler.post或最佳Activity.runOnUIThread .

相关问题