首页 > 解决方案 > BottomSheetBehavior 泄漏片段?

问题描述

我正在使用 LeakCanary 2.5 分析我的应用程序。

我很难弄清楚我在测试期间发现的最后一个内存泄漏。我真的不明白我在这里做错了什么。

LeakCanary 日志如下所示:

图片:

LeakCanary Java 内存转储映像

日志:

┬───
│ GC Root: Global variable in native code
│
├─ myApp.view.MyView instance
│    Leaking: NO (MainActivity↓ is not leaking and View attached)
│    View is part of a window view hierarchy
│    View.mAttachInfo is not null (view attached)
│    View.mID = R.id.my_view
│    View.mWindowAttachCount = 1
│    mContext instance of myApp.activity.MainActivity with mDestroyed
│    = false
│    ↓ MyView.mContext
├─ myApp.activity.MainActivity instance
│    Leaking: NO (ConstraintLayout↓ is not leaking and Activity#mDestroyed is
│    false)
│    mApplication instance of androidx.multidex.MultiDexApplication
│    mBase instance of androidx.appcompat.view.ContextThemeWrapper, not
│    wrapping known Android context
│    ↓ MainActivity._bottomSheet
├─ androidx.constraintlayout.widget.ConstraintLayout instance
│    Leaking: NO (View attached)
│    View is part of a window view hierarchy
│    View.mAttachInfo is not null (view attached)
│    View.mID = R.id.bottom_sheet
│    View.mWindowAttachCount = 1
│    mContext instance of myApp.activity.MainActivity with mDestroyed
│    = false
│    ↓ ConstraintLayout.mKeyedTags
│                       ~~~~~~~~~~
├─ android.util.SparseArray instance
│    Leaking: UNKNOWN
│    Retaining 2427 bytes in 83 objects
│    ↓ SparseArray.mValues
│                  ~~~~~~~
├─ java.lang.Object[] array
│    Leaking: UNKNOWN
│    Retaining 2394 bytes in 81 objects
│    ↓ Object[].[1]
│               ~~~
╰→ myApp.fragment.MetadataFragment instance
     Leaking: YES (ObjectWatcher was watching this because myApp.
     fragment.MetadataFragment received Fragment#onDestroy() callback and
     Fragment#mFragmentManager is null)
     Retaining 2258 bytes in 75 objects
     key = 0409b825-f199-4049-95b1-8e572c92a078
     watchDurationMillis = 6335
     retainedDurationMillis = 1335

底部工作表 XML 定义如下所示:

<androidx.constraintlayout.widget.ConstraintLayout
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/bottom_sheet"
  android:layout_width="match_parent"
  android:layout_height="100dp"
  android:background="?attr/bottom_sheet_background"
  app:behavior_hideable="false"
  app:behavior_peekHeight="55dp"
  app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">

如日志所示,我_bottomSheet在 MainActivity 中存储了一个引用。我以编程方式让 BottomSheetBehaviour 像这样BottomSheetBehavior.from(_bottomSheet);附加一个addBottomSheetCallback.

在我的活动中,onDestroy我想我清理了,但显然缺少一些东西:

@Override
protected void onDestroy()
{
  super.onDestroy();
  ...

  _bottomSheetBehavior.removeBottomSheetCallback(_bottomSheetBehaviorCallBack);
  _bottomSheet = null;

  ...
}

我想我在 LeakCanary 日志中读到的是ConstraintLayout持有一个标签到MetadataFragment. 我发现 LeakCanarymKeyedTagsViewAndroid ( ConstraintLayout extends ViewGroup-> ViewGroup extends View) 类中所指的变量。

我检查了我的代码和我的 XML,但我没有使用标签。我在这里想念什么?

安卓视图类

标签: androidmemory-leaksleakcanary

解决方案


推荐阅读