在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 的示例,但是,我无法与我的案例建立连接并使用它。
答案 0 :(得分:1)
您正在创建Runnable
Activity
中的匿名类,而匿名类包含对绑定Activity
的隐式引用。
修复我们实例化匿名时发生的内存泄漏 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)。