首页 > 解决方案 > AccessibilityManager.sInstance 是否会导致内存泄漏?

问题描述

我有一个包含片段的活动。运行 Leak Canary,我看到活动有内存泄漏。

我已经注释掉了从活动和片段到活动仅显示片段并且片段具有空的 xml 布局的所有代码。我在这两个文件或 xml 中都没有可访问性。

* AccessibilityManager$1.!(this$0)! (anonymous subclass of android.view.accessibility.IAccessibilityManagerClient$Stub)
* ↳ AccessibilityManager.!(mTouchExplorationStateChangeListeners)!
* ↳ CopyOnWriteArrayList.!(elements)!
* ↳ array Object[].!([2])!
* ↳ AccessibilityManagerCompat$TouchExplorationStateChangeListenerWrapper.!(mListener)!
* ↳ BaseTransientBottomBar$SnackbarBaseLayout$1.!(this$0)! (anonymous implementation of android.support.v4.view.accessibility.AccessibilityManagerCompat$TouchExplorationStateChangeListener)
* ↳ Snackbar$SnackbarLayout.mContext
* ↳ ContextThemeWrapper.mBase
* ↳ MessagesActivity

标签: javaandroidandroid-activityleakcanary

解决方案


好的,我确实想通了。这是 Snackbar 中的内存泄漏,它是如何重现的:https ://github.com/GC-Xi/SnackbarBug

繁殖方式

  1. 创建一个 Snackbar 并在 Activity 中引用它
  2. 不要调用 Snackbar.show()
  3. 打开和关闭活动
  4. 请注意,Activity 没有被垃圾收集,因为小吃吧有对它的引用

原因

SnackbarBaseLayout构造函数addTouchExplorationStateChangeListener()removeTouchExplorationStateChangeListener(). _ 可能应该从onDetachedFromWindow()哪里调用,因为除非被调用,否则它不会附加到窗口。addTouchExplorationStateChangeListener()onAttachedToWindow()SnackbarBaseLayoutSnackbar.show()

解决方案 1

更新到 AndroidX 并改用 com.google.android.material.snackbar.Snackbar。 https://github.com/GC-Xi/SnackbarBug/tree/solution1

解决方案 2

除非您准备好展示它,否则不要创建 Snackbar。 https://github.com/GC-Xi/SnackbarBug/tree/solution2


推荐阅读