如果未从已销毁的活动中删除,听众是否会造成内存泄漏?

8
如果在控件/视图上添加了监听器并且没有将其移除,那么会产生内存泄漏吗?例如,在onCreate中添加一个监听器到EditText以监听修改操作。在onDestroy中需要移除此监听器吗?
我想,如果使用匿名监听器或实现监听器的本地变量,则由于作用域规则,内存将在Activity被销毁时自动释放。
我唯一能想到的可能导致内存泄漏的方法是将监听器作为意图对象传递。你认为呢?

2
当您通过意图附加项传递对象时,对象的实例并没有被传递。使用可序列化或可包装接口创建了对象的副本。 - Cheryl Simon
2个回答

8

单独来说,监听器不会造成内存泄漏。但是,它们经常被错误地使用,因此可能导致泄漏。有时你会看到代码中一个对象引用了一个组件(例如,为了在那里显示消息),该组件具有监听器,该监听器又引用(可能是间接地)第一个对象。这形成了一个循环,所有成员一起生活和死亡。当组件是一个短暂存在的对话框时,你可能会遇到问题。初学者倾向于使用像

class MyKitchenSink implements Runnable, KeyListener, ....

不要创建“通用类”是解决内存泄漏问题的正确方式,这些类可能具有很多引用,从而使构建内存泄漏更加容易*


* 这并不像在C中那样是一个“真正”的内存泄漏,因为所有对象仍然可达,并且如果您想使用它们,可以使用。它只是将对象保持可达时间比预期的要长得多,这就像泄漏一样消耗内存。


3

除非控件/视图以外的东西引用了监听器,否则不应该创建内存泄漏 - 在onDestroy中不需要移除监听器...


1
这个答案基于什么?只是好奇,我可以猜测答案,但我想要一个确切的答案。 - Spidy
2
@Spidy 这就是垃圾回收的工作原理。如果没有任何引用指向一个对象,那么它就可以被销毁。因此,如果唯一引用监听器的东西都在视图内,并且该视图被销毁了,那么监听器也可以被销毁。请参阅此文章以获取有关Java中内存泄漏的更多详细信息:http://www.ibm.com/developerworks/java/library/j-leaks/ - Cheryl Simon
@Spidy,只需进行简单的实验:创建一个带有EditText的活动的简单应用程序。将onTextChange监听器添加到该editText并多次旋转您的设备。在此过程中,在Android Studio Profiler中记录您的CPU,您会发现所有活动/片段的所有实例在某个时候都被清除了。这可能不是立即完成的,但GC知道何时清理堆栈最好。 - Kirill Karmazin

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