【问题标题】:DialogFragment leaking memoryDialogFragment 泄漏内存
【发布时间】:2016-08-18 23:25:13
【问题描述】:
在我正在开发的应用程序中,我看到 DialogFragment 中存在内存泄漏,到目前为止,修复它的唯一方法是在 DialogFragment 被破坏时删除所有视图,这是正常的事情吗?做?我正在使用自定义 ROM,因此不确定这是否与此问题有关。是否有任何理由不从对话框中删除所有视图会导致它们泄漏内存?
@Override
public void onDestroyView() {
if (getView() instanceof ViewGroup) {
((ViewGroup)getView()).removeAllViews();
}
super.onDestroyView();
}
【问题讨论】:
标签:
android
memory-leaks
android-dialogfragment
【解决方案2】:
MemoryLeak 发生的原因有很多,一些常见的原因:
- 在某些静态字段中保留对象(在本例中为 DialogFragment 实例)的引用。
- 将
Context 传递给 Thread 或 AsyncTask,因为 Threads 也是 GC root!
- 您的类具有非静态内部类,在这种情况下,如果内部类与 GC 根相关(例如,如果内部类是
AsyncTask 的实例),则会发生内存泄漏。
在您的情况下,您可能有一个与 GC root 相关的视图,而该视图不能被垃圾收集,而您保留视图的对话框也不能被垃圾收集。
【解决方案3】:
我的出现可能与您的经验无关,但它确实与从 DialogFragment 中的 EditText 小部件捕获用户输入并通过回调将其发送到调用 Fragment 有关。 Leakcanary 给了我以下信息:
====================================
HEAP ANALYSIS RESULT
====================================
1 APPLICATION LEAKS
References underlined with "~~~" are likely causes.
Learn more at https://squ.re/leaks.
99628 bytes retained by leaking objects
Signature: d189c386cd77f5b37c0a05eb1a290629edee
┬───
│ GC Root: System class
│
├─ com.example.jbiss.petminder.dialogs.DurationDialogFragment class
│ Leaking: NO (a class is never leaking)
│ ↓ static DurationDialogFragment.mCallback
│ ~~~~~~~~~
╰→ com.example.jbiss.petminder.fragments.ScheduleAppointmentFragment instance
Leaking: YES (ObjectWatcher was watching this because
com.example.jbiss.petminder.fragments.ScheduleAppointmentFragment received
Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
key = 820c4d81-c97f-412b-be14-4cc17f883313
watchDurationMillis = 5169
retainedDurationMillis = 168
key = 2b74e5f3-c55c-4797-9d7a-dd2bca477a53
原来是因为我将 mCallback 声明为静态的。当我从声明中删除“静态”时,我会收到其他 DialogFragment 的 mCallback 之一的此消息。好吧,我想通了,并从所有这些 mCallback 声明中删除了“静态”,并且不再有泄漏,至少从那方面来说是这样。我不知道我为什么这样做,但我做到了,leakcanary 为我找到了它,并为我免去了未来的悲伤。