有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

共 (2) 个答案

  1. # 1 楼答案

    我也经历过类似的问题。我手里拿着一个快餐店的参考资料。在我删除了那个引用之后,这个内存泄漏就消失了

    更新

    例如,替换

    val snackbar = Snackbar.make(rootLayout, "Hello Snackbar", Snackbar.LENGTH_INDEFINITE)
    snackbar.show()
    

    Snackbar.make(rootLayout, "Hello Snackbar", Snackbar.LENGTH_INDEFINITE).show()
    

    我不知道为什么它解决了我的问题。我无法在其他项目中重现此内存泄漏。根据堆栈跟踪,系统似乎没有调用BaseTransientBottomBar.onDetachedFromWindow(),因此touchExplorationStateChangeListener不会从accessibilityManager中删除。我也不知道为什么会这样。下面是BaseTransientBottomBar.onDetachedFromWindow()的代码

        protected void onDetachedFromWindow() {
            super.onDetachedFromWindow();
            if (this.onAttachStateChangeListener != null) {
                this.onAttachStateChangeListener.onViewDetachedFromWindow(this);
            }
    
            AccessibilityManagerCompat.removeTouchExplorationStateChangeListener(this.accessibilityManager, this.touchExplorationStateChangeListener);
        } 
    
  2. # 2 楼答案

    好吧,我真的弄明白了。这是Snackbar中的内存泄漏,下面是如何复制它:https://github.com/GC-Xi/SnackbarBug

    复制方式

    1. 创建一个Snackbar并在活动中引用它
    2. 不要叫Snackbar。show()
    3. 打开并关闭活动
    4. 请注意,活动不是垃圾收集的,因为snackbar有一个对它的引用

    原因

    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