未删除的ViewTreeObserver侦听器是否会导致内存泄漏?

McF*_*ane 9 android memory-leaks

我正在使用以下方法监听视图的布局更改OnGlobalLayoutListener:

view.getViewTreeObserver().addOnGlobalLayoutListener(myListener);
Run Code Online (Sandbox Code Playgroud)

因为只要视图存在,我对这个监听器的事件感兴趣,所以我认为不需要调用removeOnGlobalLayoutListener(myListener).

这会导致内存泄漏还是与视图一起收集的侦听器垃圾?假设侦听器持有对视图的引用.


背景是我想要创建一个可以附加到某些视图的模块,并根据布局更改来完成.如果不需要删除它的创建就像创建一样简单,new FancyModule(theView)然后构造函数负责绑定侦听器.如果需要删除,我必须实现一个我想要防止的析构函数方法.

ali*_*tar 7

我遇到了同样的内存泄漏问题,我尝试在片段的 onDestroyView 中取消注册 OnGlobalLayoutListener 但问题仍然存在,然后我尝试为我的视图添加 onDetachListener ,然后取消注册 OnGlobalLayoutListener ,它成功了。

在科特林中我使用:

view?.doOnDetach {
    onGlobalLayoutListener?.let {
        view?.viewTreeObserver?.removeOnGlobalLayoutListener(it)
    }
    onGlobalLayoutListener = null
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用 addOnAttachStateChangeListener 方法。


Tom*_*mik 5

潜在的内存泄漏仅取决于您的体系结构.

通常情况下,不打电话也没关系removeOnGlobalLayoutListener(myListener). View持有参考,ViewTreeObserver其中包含添加的参考OnGlobalLayoutListener.如果您没有对侦听器的其他引用,则会沿视图收集垃圾.

现在,如果您对OnGlobalLayoutListenerhold 的实现引用了视图,那么它仍然没问题.对于Android的垃圾收集器,参考周期不是问题.

如果您有另一个包含OnGlobalLayoutListener实现引用的组件,则可以创建问题.如果组件的寿命比视图长(例如,它是通过应用程序对象保存),那么您将通过侦听器创建视图(和上下文)的内存泄漏.

在不再使用视图时不要保持视图是很重要的.如何避免泄漏视图的一种简单方法是使用WeakReference.