在我正在研究的应用程序中,我在DialogFragment中看到内存泄漏,到目前为止修复它的唯一方法是在DialogFragment被销毁时删除所有视图,这是正常的事情要做做?我正在使用自定义ROM,因此不确定是否可能与此问题有关。有没有理由不从对话框中删除所有视图会导致它们泄漏内存?
@Override
public void onDestroyView() {
if (getView() instanceof ViewGroup) {
((ViewGroup)getView()).removeAllViews();
}
super.onDestroyView();
}
答案 0 :(得分:6)
这也发生在我的应用程序中,并且我使用Leakcanary发现了泄漏。
当你有一个带EditText的Dialog时会发生这种情况。关闭包含EditText的View时,无法正确处理使用回调实现的Cursor的Blink。它根据这个偶然发生。
https://code.google.com/p/android/issues/detail?id=188551
修改强>
这就是我在dialog.dismiss()
之前做的事情:
editText.setCursorVisible(false);
dismiss();
希望这有帮助!
答案 1 :(得分:4)
MemoryLeak
可能由于多种原因而发生,一些常见原因:
Context
传递给主题或 AsyncTask ,因为主题也是 GC root !AsyncTask
的实例)。在你的情况下,你可能有一个与GC root相关的视图,而那个视图不能被垃圾收集,你保持视图的对话也不能被垃圾收集。
答案 2 :(得分:0)
我的出现可能与您的经历无关,但确实与捕获来自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声明为静态的。当我从声明中删除“ static”时,我将获得另一个DialogFragment的mCallback之一的消息。好吧,我弄清楚了,并从所有这些mCallback声明中删除了“ static”,至少从此不再泄漏了。我不知道为什么要这么做,但是我做到了,leakcanary为我找到了它,并免除了我的悲伤。