2017-08-11 69 views
0

this文章中,我修改了活动类中我的处理程序如下:呼叫后

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

你正在创建Runnable这是一个匿名类在Activity和匿名类抱到势必Activity的隐式引用。

亚历克斯·洛克伍德曾谈及这也是在同一篇文章:

要解决出现的内存泄漏时,我们实例匿名 运行的类,我们把这些变量的类 的静态字段(因为匿名类的静态实例并不持有的隐式 参考其外部类)

为了解决这个问题(来自同一文章):

/** 
    * 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的生命周期(即,将被销毁,如果活动被破坏),则不需要将其更改为静态字段。

从同一篇文章:

避免使用一个活动的非静态内部类如果 内部类实例可以活得比活动的生命周期。

从文章的注释部分另一种解决方案:

不是使Runnable的静态,你也可以只持有 (非静态)引用它,并调用 mHandler.removeCallbacks (mRunnable)inDestroy()。

+0

非常感谢您的支持。因此,在sRunnable的run方法中,我将如何调用setSomeProperties(),它是非静态的? –

+0

与'Handler'类似,您可以创建自己的'Runnable'类继承'Runnable',并在'WeakReference'中包含'Activity'实例。现在你可以用'Activity'实例调用'setSomeProperties()'。或者在本文的注释部分中提出的另一种解决方案是在Activity的'onDestroy()'中调用'mHandler.removeCallbacks(mRunnable)',而不是使'Runnable'静态。你也可以这样做。 – Bob

+0

再次感谢,这是最有帮助的。 –