5

在下面的代码 Eclipse 生成警告“这个处理程序类应该是静态的,否则可能会发生泄漏”。

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())!

4

3 回答 3

5

以下是使用弱引用和静态处理程序类来解决 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 MyHandler getHandler() {
    return new MyHandler(this);
  }
}
于 2015-01-07T18:15:55.463 回答
2

Android lint 检查

处理程序泄漏
------------
摘要:确保 Handler 类不持有对
外层

优先级:4 / 10
严重性:警告
类别:性能

在 Android 中,处理程序类应该是静态的,否则可能会发生泄漏。留言
在应用程序线程的 MessageQueue 上排队也保留了它们的目标
处理程序。如果 Handler 是一个内部类,它的外部类将被保留为
出色地。为避免泄漏外部类,请将 Handler 声明为静态嵌套
具有对其外部类的 WeakReference 的类。

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

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

什么会阻止您的消息被处理?不幸的是,lint 工具无法解决这个问题,因此它总是警告您可能存在内存泄漏。如果您确定自己在做什么,可以通过各种方法抑制这些消息。

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

于 2012-11-22T08:11:01.747 回答
2

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

想象一下情况。一些 Activity 调用PendingIntent.send(...)并将non-static inner subclass of Handler. 然后活动被破坏。但内部阶层生活

内部类仍然拥有指向已销毁活动的链接,它不能被垃圾收集。

因此,您需要将其设为静态。

资料来源:Android 中的处理程序和内存泄漏

于 2012-11-22T06:57:00.747 回答