在android活动

时间:2017-08-11 07:52:56

标签: 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);

但是,在我的活动逻辑的几个点上,我必须在这个处理程序上调用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 文件是否存在泄漏活动,我都会指向handler.post(new Runnable())行。我做错了什么?

P.S。我在处理程序上看到了许多覆盖 handleMessage 的示例,但是,我无法与我的案例建立连接并使用它。

1 个答案:

答案 0 :(得分:1)

您正在创建Runnable Activity中的匿名类,而匿名类包含对绑定Activity的隐式引用。

Alex Lockwood也在同一篇文章中谈到过这个问题:

  

修复我们实例化匿名时发生的内存泄漏   Runnable类,我们使变量成为类的静态字段   (因为匿名类的静态实例不具有隐式   参考他们的外类)

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

  /**
   * 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静态,你也可以只持有一个   (非静态)引用它并调用   onDestroy()中的mHandler.removeCallbacks(mRunnable)。