Android - 我是否必须为内部类AsyncTask使用WeakReference?

时间:2013-10-23 20:18:27

标签: android android-asynctask weak-references

LEt说我在Activity类中有一个内部类AsyncTask。 我是否必须在此AsyncTask中使用weakRefeernce?

另外,我是否必须始终为AsyncTask提供weakReference?

最后,如果我将内部类AsyncTask声明为静态,是否安全?

3 个答案:

答案 0 :(得分:2)

是的,如果它是一个内部类,或者只是创建它自己的类,那么总是声明你的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)开始,垃圾收集器更积极地收集软/弱引用,这使得它们相当无效。

答案 1 :(得分:1)

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传递给构造函数。 (我假设您在构造函数中编写了上面显示的赋值语句。

答案 2 :(得分:1)

如果你出于正当的理由使用WeakReference,那么拥有一个积极的垃圾收集器应该不会打扰你。

WeakReference表示如果没有其他人强烈指向该对象,您就不会将该对象保留在内存中。

例如,让AsyncTask传递ImageView以将图片加载到其中。

AsyncTask完成工作后,如果没有人指向带有强引用的图片视图,则表示用户不再看到ImageView它的视图已被破坏,为什么你可能想要一个已经取消屏幕的视图的引用。

所以,我认为AsyncTask中的所有引用都应该是弱的,特别是与UI相关的引用&#34;视图,活动&#34;像这样的东西。

是的,你应该尽可能地将你的内部类声明为static,所以他们没有对其包含类的隐式引用,这会破坏我们尝试使用的内容WeakReference