非静态内部类对象将拥有外部类对象的引用,如果匿名对象(如视图OnClickListener或网络响应回调)的生命周期比Activity或其他外部类对象长,这种情况会导致内存泄漏吗?如果会,应该怎么解决?
非静态内部类对象将拥有外部类对象的引用,如果匿名对象(如视图OnClickListener或网络响应回调)的生命周期比Activity或其他外部类对象长,这种情况会导致内存泄漏吗?如果会,应该怎么解决?
是的,这种情况会导致内存泄漏。
为了避免/修复此问题:
- 不要保持长期引用(使用WeakReference)
- 避免非静态内部类
- 在onDestroy()中清理/停止所有处理程序/侦听器
请看这个项目
https://github.com/AliEsaAssadi/avoid-memory-leak-android
我解释和展示了Android开发中常见的内存泄漏模式以及如何修复它们。
如何避免网络响应回调内存泄漏
在此AsyncTask示例中,您将了解如何避免在使用内部类/静态类时出现内存泄漏,并展示使用WeakReference的最佳实用方法来创建网络响应回调。
Activity
中有匿名类声明,例如事件回调,那么它不会引起任何问题,因为其生命周期将与Activity
生命周期耦合,并且没有Activity
存在时它甚至不会持续。但是,当涉及网络调用时,由于它们是在后台工作线程上执行的,因此它具有不同的生命周期和范围,而不是Activity
。因此,如果您有非静态的Asynctaks,Hanlders
等,则它们可以长时间存在而不依赖于Activity
生命周期,如果处理不当会导致内存泄漏。
解决方案
activity
即onDestroy
方法时取消所有后台任务或网络调用。AsynTask
或Handlers
创建静态内部类,并传递context
的弱引用(如果需要)。
Activity
存在,它甚至无法持续存在”,这是如何保证的?我曾经尝试在Activity
的static
字段中存储一个Button
的WeakReference
,即使在Activity
被销毁(使用开发选项“不保留活动”完成并通过adb触发gc
),我仍然可以检索到该View
并且它仍然有效。 - Meow Cat 2012