My Dialog Fragment保持内存泄漏,尽管我已经在onDestroyView的覆盖中设置了binding = null
。这是我的onCreateView和onDestroyView:
@AndroidEntryPoint
class AddressDialogFragment : BottomSheetDialogFragment() {
private var binding: FragmentAddressDialogBinding? = null
private val viewModel: AddressViewModel by activityViewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding =
DataBindingUtil.inflate(inflater, R.layout.fragment_address_dialog, container, false)
binding?.viewModel = viewModel
binding?.lifecycleOwner = this.viewLifecycleOwner
// doing my things
val view = binding?.root
return view!!
}
}
override fun onDestroyView() {
binding = null
super.onDestroyView()
}
我使用导航组件导航到这个DiaLogFragment,但不认为这是个问题。我使用过binding.unbind()
或dismiss()
对话框Fragmet,但它没有用。我还检查了DialogFragment是否已经调用了onDestroyView和onDestroy。
这是我从LeakCanary得到的泄漏(1次打开和关闭对话框时有2次泄漏,但只有1次不同的泄漏(:
│ GC Root: System class
│
├─ android.view.accessibility.AccessibilityManager class
│ Leaking: NO (a class is never leaking)
│ ↓ static AccessibilityManager.sInstance
│ ~~~~~~~~~
├─ android.view.accessibility.AccessibilityManager instance
│ Leaking: UNKNOWN
│ Retaining 374.7 kB in 8787 objects
│ ↓ AccessibilityManager.mTouchExplorationStateChangeListeners
│ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
├─ android.util.ArrayMap instance
│ Leaking: UNKNOWN
│ Retaining 374.4 kB in 8775 objects
│ ↓ ArrayMap.mArray
│ ~~~~~~
├─ java.lang.Object[] array
│ Leaking: UNKNOWN
│ Retaining 374.4 kB in 8773 objects
│ ↓ Object[0]
│ ~~~
├─ com.google.android.material.textfield.DropdownMenuEndIconDelegate$7 instance
│ Leaking: UNKNOWN
│ Retaining 14.9 kB in 264 objects
│ Anonymous class implementing android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
│ ↓ DropdownMenuEndIconDelegate$7.this$0
│ ~~~~~~
├─ com.google.android.material.textfield.DropdownMenuEndIconDelegate instance
│ Leaking: UNKNOWN
│ Retaining 14.9 kB in 263 objects
│ context instance of androidx.appcompat.view.ContextThemeWrapper, wrapping activity com.example.aposs_buyer.
│ uicontroler.activity.AddressActivity with mDestroyed = false
│ ↓ EndIconDelegate.textInputLayout
│ ~~~~~~~~~~~~~~~
├─ com.google.android.material.textfield.TextInputLayout instance
│ Leaking: YES (View detached yet still part of window view hierarchy)
│ Retaining 12.4 kB in 298 objects
│ View is part of a window view hierarchy
│ View.mAttachInfo is null (view detached)
│ View.mWindowAttachCount = 1
│ mContext instance of androidx.appcompat.view.ContextThemeWrapper, wrapping activity com.example.aposs_buyer.
│ uicontroler.activity.AddressActivity with mDestroyed = false
│ ↓ View.mParent
├─ android.widget.LinearLayout instance
│ Leaking: YES (TextInputLayout↑ is leaking and View detached yet still part of window view hierarchy)
│ Retaining 157.8 kB in 3879 objects
│ View is part of a window view hierarchy
│ View.mAttachInfo is null (view detached)
│ View.mWindowAttachCount = 1
│ mContext instance of dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper, wrapping
│ activity com.example.aposs_buyer.uicontroler.activity.AddressActivity with mDestroyed = false
│ ↓ View.mParent
╰→ androidx.core.widget.NestedScrollView instance
Leaking: YES (ObjectWatcher was watching this because com.example.aposs_buyer.uicontroler.fragment.
AddressDialogFragment received Fragment#onDestroyView() callback (references to its views should be cleared to
prevent leaks) and View detached yet still part of window view hierarchy)
Retaining 39.2 kB in 782 objects
key = 3588963a-7778-4442-ac60-a99f5380ede0
watchDurationMillis = 281964
retainedDurationMillis = 276959
View is part of a window view hierarchy
View.mAttachInfo is null (view detached)
View.mWindowAttachCount = 1
mContext instance of dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper, wrapping
activity com.example.aposs_buyer.uicontroler.activity.AddressActivity with mDestroyed = false
我希望我很快就能得到答案。我已经坚持了两天了。
我刚刚发现这是Materials Design库的TextInputLayout的泄漏。我所需要做的就是将材料设计从1.6.0更新到1.7.0implementation 'com.google.android.material:material:1.7.0'
相关链接帮助我弄清楚它在这里:https://github.com/material-components/material-components-android/issues/2615
这里应该在onPause()
或onDestroy()
方法中调用dismiss()
方法。取决于您的需求,否则它将在bottomSheetFragment的实例保持活动时创建内存泄漏。