java - 在 android Activity 中调用静态处理程序上的 post

标签 java android memory-leaks static inner-classes

已关注 this我在 Activity 类中修改了我的处理程序,如下所示:

private static class ActivityHandler extends Handler
{
    private final WeakReference<MyActivity> mActivity;

    public ActivityHandler(MyActivity activity)
    {
        mActivity = new WeakReference< MyActivity >(activity);
    }

    public final MyActivity getActivity()
    {
        return mActivity.get();
    }
}

处理程序已初始化:

ActivityHandler handler = new ActivityHandler(this);

但是,在我的 Activity 逻辑的几个点中,我必须在此处理程序上调用 post 。所以代替这个:

handler.post(new Runnable()
        {
            @Override
            public void run()
            {
                setSomeProperties();
            }
        });

我现在这样做:

handler.post(new Runnable()
        {
            @Override
            public void run()
            {
                MyActivity activity = handler.getActivity();
                if (activity != null)
                {
                    activity.setSomeProperties();
                }
            }
        });

当我运行应用程序并检查 hprof 文件中是否存在泄露的 Activity 时,无论发生什么变化,我仍然会被指向 handler.post(new Runnable())线。我做错了什么?

附:我见过许多在处理程序上重写 handleMessage 的示例,但是,我无法与我的案例建立连接并使用它。

最佳答案

您正在创建 Runnable,它是 Activity 中的一个匿名类,并且匿名类持有对绑定(bind) Activity 的隐式引用。

亚历克斯·洛克伍德也在同一篇文章中谈到了这一点:

To fix the memory leak that occurs when we instantiate the anonymous Runnable class, we make the variable a static field of the class (since static instances of anonymous classes do not hold an implicit reference to their outer class)

要解决这个问题(来自同一篇文章):

  /**
   * Instances of anonymous classes do not hold an implicit
   * reference to their outer class when they are "static".
   */
  private static final Runnable sRunnable = new Runnable() {
      @Override
      public void run() { /* ... */ }
  };

但是,我想说,如果 Runnable 不会超过 Activity 的生命周期(即,如果 Activity 被销毁,则 Runnable 会被销毁),则无需将其更改为静态字段。

来自同一篇文章:

Avoid using non-static inner classes in an activity if instances of the inner class could outlive the activity’s lifecycle.

文章评论部分的另一个解决方案:

Instead of making the Runnable static, you could also just hold a (non-static) reference to it and call mHandler.removeCallbacks(mRunnable) in onDestroy().

关于java - 在 android Activity 中调用静态处理程序上的 post,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45629792/

相关文章:

java - 如何在 Eclipse Java 动态 Web 项目中使用 .properties 文件?

android - TestScheduler 不起作用(Kotlin + RxJava2 + mockito)

http - 在 Golang 中为 http.Response 使用空白标识符是否足以防止内存泄漏?

google-chrome - 使用 Canvas drawImage 方法在谷歌浏览器中增加奇怪的内存

memory-leaks - 客户端 websocket 实现

java - javac中-source的使用

java - 是否有 OSGi Web 服务/SOAP 客户端?

java - 将 .jui 文件转换为 .java 文件,qt-jamba

java - 单击 TextView 打开计算器

正文消息上的 Android GmailSender 错误