1

我正在使用LeakCanary来识别内存泄漏。我有一个 Activity 将自身添加为 onResume 中的 StatusChangeObserver,如下所示:

    final int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING |
            ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;

    mSyncObserverHandle = ContentResolver.addStatusChangeListener(mask, this);

并停止监听 onPause

    ContentResolver.removeStatusChangeListener(mSyncObserverHandle);

当我退出 Activity 时,LeakCanary 报告我的 Activity 被泄露。以下是泄漏跟踪的要点:

     * com.sample.android.MyListActivity has leaked:
     * GC ROOT android.content.ContentResolver$1.val$callback(anonymous class extends android.content.ISyncStatusObserver$Stub)
     * leaks com.sample.android.MyListActivity instance
     [ 06-11 15:35:23.123 11823:13392 D/LeakCanary ]
     * Reference Key: 1eaf447d-055c-4767-bb3f-56b12c7a4dae
     * Device: motorola motorola XT1022 condor_retaildsds
     * Android Version: 4.4.4 API: 19 LeakCanary: 1.3.1
     * Durations: watch=5029ms, gc=147ms, heap dump=693ms, analysis=15159ms
     [ 06-11 15:35:23.123 11823:13392 D/LeakCanary ]

我已经在 API 19 和 22 上进行了测试。我想知道我的代码、leakcanary 或 sdk 是否有问题。

提前致谢!

4

1 回答 1

0

我遇到了同样的问题,在使用 LeakCanary 库和 Memory Analyzer Tool 测试我的应用程序的内存问题或泄漏后,我发现我的 SyncStatusObserver 实例正在泄漏我的 Activity。根据我对匿名类的理解,这种泄漏的最合理原因似乎是匿名类隐式引用包含类,如果它们被声明为非静态的。因此,我将 mSyncStatusObserver 声明为静态(可能不会在没有明确引用的情况下引用包含的类成员)并且在再次测试后泄漏消失了

 private SyncStatusObserver mSyncStatusObserver = new SyncStatusObserver() {

    /** Callback invoked with the sync adapter status changes. */
    @Override
    public void onStatusChanged(int which) {
    ....
    }

在我的简历中

protected void onResume() {
    super.onResume();
    mSyncStatusObserver.onStatusChanged(0);

    // Watch for sync state changes
    final int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING |
            ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;
    mSyncObserverHandle = ContentResolver.addStatusChangeListener(mask, mSyncStatusObserver);
}

在我的 onStop 我删除了监听器

 @Override
  protected void onStop() {
    super.onStop();
    if (mSyncObserverHandle != null) {
        ContentResolver.removeStatusChangeListener(mSyncObserverHandle);
        mSyncObserverHandle = null;
       // mSyncStatusObserver = null;
    }
}

我是Android开发的新手,我不完全确定我提供的解释是否完全正确,所以如果有人必须提供更好的解决方案,欢迎

于 2015-09-21T18:33:47.630 回答