gpt4 book ai didi

android - 由于 Snackbar 导致的内存泄漏

转载 作者:行者123 更新时间:2023-11-29 16:29:40 29 4
gpt4 key购买 nike

我刚刚将 CanaryLeak 添加到我的项目中,以查看我的应用程序中是否存在任何内存泄漏,并注意到,由于 Snackbar,我的一个 fragment 中确实存在泄漏。

我在 onCreateView 中创建了一个 Snackbar,并在 onDestroyView 中将其设置为 null。但是,每次旋转屏幕时都会发生内存泄漏。


@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup
container, Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.fragment_backend, container,
false);

Activity parentActivity = getActivity();
if (parentActivity != null) {
mConnectSnackbar =
Snackbar.make(parentActivity.findViewById(R.id.nav_host_fragment),
"Connect", Snackbar.LENGTH_INDEFINITE);

mConnectSnackbar.setAction(getString(R.string.connect), v ->
startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS)));
}

return view;
}

@Override
public void onDestroyView() {
super.onDestroyView();
mConnectSnackbar.setAction("Connect", null);
mConnectSnackbar.dismiss();
mConnectSnackbar = null;
}

当我清除对操作和 Snackbar 本身的引用时,不应该有任何内存泄漏的原因。但是我无法弄清楚,原因可能是什么,来自 Canary Leak 的堆转储也无济于事。由于引用了 nav_host_fragment,我怀疑这可能是我造成的,但我不知道这是否属实以及如何解决。

非常感谢您的帮助。

编辑 1:

添加了 Leak Trace 并删除了 hprof 文件。


├─ android.view.accessibility.AccessibilityManager
│ Leaking: NO (a class is never leaking)
│ GC Root: System class
│ ↓ static AccessibilityManager.sInstance
│ ~~~~~~~~~
├─ android.view.accessibility.AccessibilityManager
│ Leaking: UNKNOWN
│ ↓ AccessibilityManager.mTouchExplorationStateChangeListeners
│ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
├─ android.util.ArrayMap
│ Leaking: UNKNOWN
│ ↓ ArrayMap.mArray
│ ~~~~~~
├─ java.lang.Object[]
│ Leaking: UNKNOWN
│ ↓ array Object[].[4]
│ ~~~
├─ androidx.core.view.accessibility.AccessibilityManagerCompat$TouchExplorationStateChangeListenerWrapper
│ Leaking: UNKNOWN
│ ↓ AccessibilityManagerCompat$TouchExplorationStateChangeListenerWrapper.mListener
│ ~~~~~~~~~
├─ com.google.android.material.snackbar.BaseTransientBottomBar$SnackbarBaseLayout$1
│ Leaking: UNKNOWN
│ ↓ BaseTransientBottomBar$SnackbarBaseLayout$1.this$0
│ ~~~~~~
╰→ com.google.android.material.snackbar.Snackbar$SnackbarLayout
​ Leaking: YES (View.mContext references a destroyed activity)
​ mContext instance of android.view.ContextThemeWrapper, wrapping activity com.twaice.twaice.MainActivity with mDestroyed = true
​ View#mParent is null
​ View#mAttachInfo is null (view detached)
​ View.mWindowAttachCount = 0

最佳答案

这是 material-components-android 库中的内存泄漏。我刚刚提交了一个问题:https://github.com/material-components/material-components-android/issues/497

只有创建了一个 snackbar 但从未像问题中描述的那样显示时才会发生此泄漏:

In Material Library 1.0.0, when a BaseTransientBottomBar .SnackbarBaseLayout instance is created, it registers a TouchExplorationStateChangeListener which it then unregisters onDetachedFromWindow(). If the SnackbarBaseLayout is created but never attached (which happens), then it never gets detached. When the underlying context (an activity) gets destroyed, the TouchExplorationStateChangeListener is kept in memory by AccessibilityManager, holding on to its outer class SnackbarBaseLayout which itself holds on to its context, a destroyed activity. Effectively SnackbarBaseLayout is leaking destroyed activities and the entire view hierarchy.

好消息是此代码在 1.1.0 版本中不再存在,因此泄漏已经消失,但不幸的是 1.1.0 仍处于 alpha 版本中。

注意:在以后的帖子中,考虑提供 LeakCanary 输出的文本泄漏跟踪,这对于解决内存泄漏很有用。

关于android - 由于 Snackbar 导致的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57338450/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com