呼叫后
问题描述:
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,但是,我还没有能够与我的案例建立连接并使用它。
答
你正在创建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()。
非常感谢您的支持。因此,在sRunnable的run方法中,我将如何调用setSomeProperties(),它是非静态的? –
与'Handler'类似,您可以创建自己的'Runnable'类继承'Runnable',并在'WeakReference'中包含'Activity'实例。现在你可以用'Activity'实例调用'setSomeProperties()'。或者在本文的注释部分中提出的另一种解决方案是在Activity的'onDestroy()'中调用'mHandler.removeCallbacks(mRunnable)',而不是使'Runnable'静态。你也可以这样做。 – Bob
再次感谢,这是最有帮助的。 –