【发布时间】:2013-10-23 20:18:27
【问题描述】:
假设我在 Activity 类中有一个内部类 AsyncTask。 我必须在这个 AsyncTask 中有弱引用吗?
另外,我是否必须一直为 AsyncTask 提供弱引用?
最后,如果我将内部类 AsyncTask 声明为静态,是否安全?
【问题讨论】:
标签: android android-asynctask weak-references
假设我在 Activity 类中有一个内部类 AsyncTask。 我必须在这个 AsyncTask 中有弱引用吗?
另外,我是否必须一直为 AsyncTask 提供弱引用?
最后,如果我将内部类 AsyncTask 声明为静态,是否安全?
【问题讨论】:
标签: android android-asynctask weak-references
是的,如果你的Asynctask是一个内部类,或者只是创建它自己的类,总是声明你的静态类,尽量避免声明为非静态内部类,因为它会造成内存泄漏。 Read here for a more elaborate explanation why you should not do this
您不想将WeakReference 用于 Asynctask,因为 android 2.3+ 的垃圾收集器非常激进,并且会非常快速地收集所有弱引用。弱引用通常也不是线程的好模式,它更多的是用于内存占用大的对象,如位图(但在 android 中不再是如前所述)。
来自http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
从 Android 2.3(API 级别 9)开始,垃圾收集器更加积极地收集软/弱引用,这使得它们相当无效。
【讨论】:
WeakReference 允许对 Activity 进行垃圾回收,因此不会发生内存泄漏。
空引用意味着AsyncTask 不能盲目地尝试更新不再附加的用户界面,这会引发异常(例如,视图未附加到窗口管理器)。当然,您必须检查 null 以避免 NPE。因此,使用WeakReference 处理上述情况是一个好习惯。
是的,将你的内部类声明为static
WeakReference<Activity> weakActivity;
AsyncTask 中的某处,可能是构造函数或 onPreExecute:
weakActivity = new WeakReference<Activity>(activity);
在onPostExecute:
Activity activity = weakActivity.get();
if (activity != null) {
// do your stuff with activity here
}
从您启动AsyncTask 的活动中,将this 传递给构造函数。 (我假设您在构造函数中编写了上面显示的赋值语句。
【讨论】:
如果您出于正确的原因使用WeakReference,那么拥有积极的垃圾收集器应该不会打扰您。
WeakReference 表示如果没有其他人强烈指向该对象,则您对该对象不感兴趣。
例如,有一个 AsyncTask 传递一个 ImageView 来加载图像。
AsyncTask 完成后,如果没有人指向具有强引用的图像视图,则意味着ImageView 不再对用户可见,并且它的视图已被破坏,所以为什么您是否希望引用已从屏幕上移除的视图。
所以是的,我相信您在 AsyncTask 中的所有引用都应该是弱引用,特别是与 UI“视图、活动”之类的东西相关的引用。
是的,你应该尽可能将你的内部类声明为static,这样它们就没有对其包含类的隐式引用,这将破坏我们使用WeakReference所做的尝试
【讨论】: