【问题标题】:LeakCanary - Activity is leaked as it implements SyncStatusObserverLeakCanary - Activity 在实现 SyncStatusObserver 时被泄露
【发布时间】:2015-06-11 10:30:58
【问题描述】:

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

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

    mSyncObserverHandle = ContentResolver.addStatusChangeListener(mask, this);

在暂停时停止收听

    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 是否有问题。

提前致谢!

【问题讨论】:

    标签: android memory-leaks leakcanary


    【解决方案1】:

    我遇到了同样的问题,在使用 LeakCanary 库和内存分析器工具测试我的应用程序的内存问题或泄漏后,我发现我的 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 开发的新手,我不完全确定我提供的解释是否完全正确,因此欢迎任何人提供更好的解决方案

    【讨论】:

      猜你喜欢
      • 2017-07-16
      • 2020-02-06
      • 2012-04-04
      • 2018-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      • 2016-06-26
      相关资源
      最近更新 更多