【问题标题】: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();
    }

【问题讨论】:

  • 要确认它,您还应该尝试使用非 root 手机

标签: android memory-leaks android-dialogfragment


【解决方案1】:

这也发生在我的应用上,我使用 Leakcanary 发现了泄漏。

当您有一个带有 EditText 的对话框时会发生这种情况。使用回调实现的光标闪烁在关闭包含 EditText 的视图时未正确处理。它是根据这个偶然发生的。

https://code.google.com/p/android/issues/detail?id=188551

编辑

这就是我在每个dialog.dismiss()之前所做的:

editText.setCursorVisible(false);
dismiss();

希望这会有所帮助!

【讨论】:

  • 应该标记为正确答案。修复了我的问题。谢谢!
【解决方案2】:

MemoryLeak 发生的原因有很多,一些常见的原因:

  • 在某些静态字段中保留对象(在本例中为 DialogFragment 实例)的引用。
  • Context 传递给 ThreadAsyncTask,因为 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 为我找到了它,并为我免去了未来的悲伤。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-28
      • 1970-01-01
      • 2014-08-23
      • 1970-01-01
      • 2016-08-20
      • 2011-10-08
      • 2013-01-20
      相关资源
      最近更新 更多