观察者和网络回调会导致内存泄漏问题吗?

3

非静态内部类对象将拥有外部类对象的引用,如果匿名对象(如视图OnClickListener或网络响应回调)的生命周期比Activity或其他外部类对象长,这种情况会导致内存泄漏吗?如果会,应该怎么解决?

2个回答

3

是的,这种情况会导致内存泄漏。

为了避免/修复此问题:

  1. 不要保持长期引用(使用WeakReference)
  2. 避免非静态内部类
  3. 在onDestroy()中清理/停止所有处理程序/侦听器

请看这个项目

https://github.com/AliEsaAssadi/avoid-memory-leak-android

我解释和展示了Android开发中常见的内存泄漏模式以及如何修复它们。

如何避免网络响应回调内存泄漏

在此AsyncTask示例中,您将了解如何避免在使用内部类/静态类时出现内存泄漏,并展示使用WeakReference的最佳实用方法来创建网络响应回调。


1
如果在您的Activity中有匿名类声明,例如事件回调,那么它不会引起任何问题,因为其生命周期将与Activity生命周期耦合,并且没有Activity存在时它甚至不会持续。但是,当涉及网络调用时,由于它们是在后台工作线程上执行的,因此它具有不同的生命周期和范围,而不是Activity。因此,如果您有非静态的Asynctaks,Hanlders等,则它们可以长时间存在而不依赖于Activity生命周期,如果处理不当会导致内存泄漏。 解决方案
  1. 在销毁activityonDestroy方法时取消所有后台任务或网络调用。
  2. AsynTaskHandlers创建静态内部类,并传递context的弱引用(如果需要)。

“而且如果没有Activity存在,它甚至无法持续存在”,这是如何保证的?我曾经尝试在Activitystatic字段中存储一个ButtonWeakReference,即使在Activity被销毁(使用开发选项“不保留活动”完成并通过adb触发gc),我仍然可以检索到该View并且它仍然有效。 - Meow Cat 2012
“gc” 周期如此随机,我们无法保证垃圾回收会立即发生,但最好假设它已经发生以避免问题。 - Rajan Kali
嗯...也许吧。我认为对于像视图和监听器这样的小东西,在用户关闭应用程序之前会泄漏太多内存。无论如何,谢谢~ 喵。 - Meow Cat 2012

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接