java为什么要使用AccessibilityManager是有原因的。sInstance会导致内存泄漏吗?
我有一个包含片段的活动。运行Leak Canary,我发现该活动存在内存泄漏
我已经注释掉了从activity和fragment到activity只显示片段的所有代码,片段有一个空的xml布局。我在文件或xml中都没有可访问性
* AccessibilityManager$1.!(this$0)! (anonymous subclass of 安卓.view.accessibility.IAccessibilityManagerClient$Stub)
* ↳ AccessibilityManager.!(mTouchExplorationStateChangeListeners)!
* ↳ CopyOnWriteArrayList.!(elements)!
* ↳ array Object[].!([2])!
* ↳ AccessibilityManagerCompat$TouchExplorationStateChangeListenerWrapper.!(mListener)!
* ↳ BaseTransientBottomBar$SnackbarBaseLayout$1.!(this$0)! (anonymous implementation of 安卓.support.v4.view.accessibility.AccessibilityManagerCompat$TouchExplorationStateChangeListener)
* ↳ Snackbar$SnackbarLayout.mContext
* ↳ ContextThemeWrapper.mBase
* ↳ MessagesActivity
# 1 楼答案
我也经历过类似的问题。我手里拿着一个快餐店的参考资料。在我删除了那个引用之后,这个内存泄漏就消失了
更新
例如,替换
与
我不知道为什么它解决了我的问题。我无法在其他项目中重现此内存泄漏。根据堆栈跟踪,系统似乎没有调用
BaseTransientBottomBar.onDetachedFromWindow()
,因此touchExplorationStateChangeListener
不会从accessibilityManager
中删除。我也不知道为什么会这样。下面是BaseTransientBottomBar.onDetachedFromWindow()
的代码# 2 楼答案
好吧,我真的弄明白了。这是Snackbar中的内存泄漏,下面是如何复制它:https://github.com/GC-Xi/SnackbarBug
复制方式
原因
SnackbarBaseLayout
在构造函数中调用addTouchExplorationStateChangeListener()
,在onDetachedFromWindow()
中调用removeTouchExplorationStateChangeListener()
。其中addTouchExplorationStateChangeListener()
可能应该从onAttachedToWindow()
调用,因为SnackbarBaseLayout
没有附加到窗口,除非调用Snackbar.show()
解决方案1
更新到AndroidX并使用com。谷歌。安卓布料小吃吧。取而代之的是Snackbar。 https://github.com/GC-Xi/SnackbarBug/tree/solution1
解决方案2
除非准备好显示,否则不要创建Snackbar。 https://github.com/GC-Xi/SnackbarBug/tree/solution2