假设我在一个活动类中有一个内部类AsyncTask。 我必须在这个AsyncTask中使用weakReference吗?
此外,我是否必须始终为AsyncTask使用weakReference?
最后,如果我将内部类AsyncTask声明为static,它是安全的吗?
假设我在一个活动类中有一个内部类AsyncTask。 我必须在这个AsyncTask中使用weakReference吗?
此外,我是否必须始终为AsyncTask使用weakReference?
最后,如果我将内部类AsyncTask声明为static,它是安全的吗?
如果 Asynctask
是一个内部类,你应该始终将其声明为静态的,或者创建一个属于它自己的类。尽量避免声明为非静态内部类,因为这会导致内存泄漏。在这里阅读更详细的解释,为什么你不应该这么做
你不应该使用 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);
Activity activity = weakActivity.get();
if (activity != null) {
// do your stuff with activity here
}
AsyncTask
的活动中,将 this
传递给构造函数。(我假设你在构造函数中编写了上面显示的赋值语句。)WeakReference
的原因正确,那么有一个积极的垃圾回收器不应该困扰您。
WeakReference
意味着如果没有其他人强烈指向它,您对于保留该对象在内存中并不感兴趣。ImageView
传递给AsyncTask
以加载图像。AsyncTask
完成其工作后,如果没有人用强引用指向该图像视图,则表示该ImageView
对用户不再可见,其视图已被销毁,那么为什么您可能想要引用已经从屏幕上移除的视图呢?AsyncTask
中的所有引用都应该是弱引用,特别是与UI相关的“视图、活动”之类的东西。WeakReference
所尝试做的事情。