【问题标题】:This Handler class should be static or leaks may occur (null)这个 Handler 类应该是静态的,否则可能会发生泄漏(null)
【发布时间】:2015-06-13 15:12:34
【问题描述】:
This Handler class should be static or leaks may occur (null)

此消息的“类”是否指的是“MyActivity”,因为 Handler 是一个对象,而我确实将其声明为静态的。我应该忽略它还是应该添加一些东西,比如“MyActivity”声明中的某个地方的“静态”(我试过这个并得到错误)。我注意到此 lint 警告通常建议使用“WeakReference”。

public class MyActivity extends Activity{
...
static Handler handler;
...
handler = new Handler()
  {
    public void handleMessage(Message msg) {

【问题讨论】:

  • 不,如果您实例化一个内部处理程序类,您应该使该类本身静态以避免泄漏。现在您正在使用非静态的默认类构造函数,您可以创建自己的内部类来扩展处理程序并且是静态的以修复警告。
  • 只有当您使用任何类型的“延迟”执行并且最后没有清空消息队列时,才会存在“可能发生泄漏”的风险

标签: android handler


【解决方案1】:

因为 Handler 是一个对象,我确实将它声明为静态

您将 数据成员 声明为静态的。但是,您使用的是匿名内部类,因此您的 Handler 子类不是 static

代替:

  handler = new Handler() {
    public void handleMessage(Message msg) {
      // do cool stuff
    }
  };

使用:

handler=new MyVeryOwnHandler();

其中MyVeryOwnHandler 是常规Java 类或static 内部类:

private static class MyVeryOwnHandler extends Handler {
  public void handleMessage(Message msg) {
      // do cool stuff
  }
};

注意错误是class需要是static;它并没有说 object 必须是static

【讨论】:

  • 感谢您对这种情况下的错误的简明解释以及我应该做什么的示例。我发现一个优雅的例子值一千字。尝试添加“私有”或“静态”时出现“此处不允许修改器静态”,但仅使用“MyVeryOwnHandler 类扩展处理程序”即可工作并消除泄漏警告。
  • @michael: 如果MyVeryOwnHandler 是它自己的顶级Java 类,在MyVeryOwnHandler.java 文件中,您将不需要(或被允许使用)privatestatic。但是,如果 MyVeryOwnHandlerMyActivity 的内部类,则 privatestatic 变得相关。
  • 它不允许我在我的主要活动的 onCreate 中声明 MyHandler 时使用 'static' 或 'private',尽管只是创建没有 'private' 或 'static' 的新类确实消除了错误警告。我在这里找到了一篇有趣的文章:androiddesignpatterns.com/2013/01/…,尽管他们的解决方案更复杂。在 onCreate 之外声明类是不方便的,因为我的处理程序处理 adview、inappPurchasing、插页式广告、排行榜等必须重新声明为静态且某些方法无法识别。
  • @michael:“在我的主要活动的 onCreate 中声明 MyHandler 时,它不允许我使用 'static' 或 'private'” - 这是因为 MyVeryOwnHandler,从我的回答中,未在 onCreate() 中定义。它在onCreate()实例化。但是,它是在 Activity 的任何方法之外定义的,因为这就是您在 Java 中定义静态类和内部类的方式。
  • 真的,谢谢。我希望在 onCreate 中定义它的新类,我几乎必须为它处理的所有事情做这件事,并且使用“静态私有处理程序处理程序”声明处理程序会改进它,尽管从我读过的内容来看它可以仍然泄漏。无论如何,我不使用延迟操作或大型多条消息。我可能不得不在下面尝试 Julianemailde 的新答案,以将处理程序类保留在 onCreate 中。
【解决方案2】:

为了避免泄漏,我还迁移到了静态嵌套类。 Android Studio 的解释是这样说的,它可能会有所帮助:

由于这个 Handler 被声明为一个内部类,它可能会阻止 外部类被垃圾收集。 如果处理程序正在使用 Looper 或 MessageQueue 用于主线程以外的线程,然后 没有问题。 如果 Handler 使用 Looper 或 MessageQueue 在主线程中,您需要修复您的 Handler 声明,如 如下:将Handler声明为静态类;在外层, 实例化一个到外部类的 WeakReference 并将这个对象传递给 实例化处理程序时的处理程序;使所有参考 使用 Wea​​kReference 对象的外部类的成员。

在迁移之前,我按照developer.android.com 的建议使用了 Looper 线程的实现,这最终导致了警告。 *从头开始

  class LooperThread extends Thread {
  public Handler mHandler;

  public void run() {
      Looper.prepare();

      mHandler = new Handler() {
          public void handleMessage(Message msg) {
              // process incoming messages here
          }
      };

      Looper.loop();
  }  
 }

【讨论】:

    猜你喜欢
    • 2012-11-10
    • 2013-09-22
    • 2012-07-09
    • 2013-08-14
    • 2020-09-06
    • 2017-11-02
    • 2020-10-30
    相关资源
    最近更新 更多