在 android activity 中的静态处理程序上调用 post
Calling post on a static handler within android activity
根据 this 文章,我在 Activity class 中修改了我的处理程序,如下所示:
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 文件中泄露的活动时,无论发生什么变化,我仍然会指向 handler.post(new Runnable())
行。我做错了什么?
p.s。我已经看到许多示例覆盖处理程序上的 handleMessage,但是,我无法与我的案例建立联系并使用它。
您正在创建 Runnable
,它是您 Activity
中的匿名 class,并且匿名 class 持有对绑定 Activity
的隐式引用。
Alex Lockwood 在同一篇文章中也谈到了这一点:
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 被销毁就会被销毁),则无需更改那到静态字段。
来自同一篇文章:
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().
根据 this 文章,我在 Activity class 中修改了我的处理程序,如下所示:
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 文件中泄露的活动时,无论发生什么变化,我仍然会指向 handler.post(new Runnable())
行。我做错了什么?
p.s。我已经看到许多示例覆盖处理程序上的 handleMessage,但是,我无法与我的案例建立联系并使用它。
您正在创建 Runnable
,它是您 Activity
中的匿名 class,并且匿名 class 持有对绑定 Activity
的隐式引用。
Alex Lockwood 在同一篇文章中也谈到了这一点:
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 被销毁就会被销毁),则无需更改那到静态字段。
来自同一篇文章:
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().