KeyguardManager Утечка памяти - PullRequest
       28

KeyguardManager Утечка памяти

1 голос
/ 01 марта 2020

Я использую этот код для DismissKeyguard после завершения активности. LeakCanary отображает сообщение ниже. как предотвратить эти утечки.

keyguardManager = (KeyguardManager) getSystemService(Activity.KEYGUARD_SERVICE);

if(Build.VERSION.SDK_INT >= 27) {

    setShowWhenLocked(true);
    setTurnScreenOn(true);

    if (keyguardManager != null) {
        keyguardManager.requestDismissKeyguard(this, null);
    }
}

LeakCanary показывает

GC Root: Global variable in native code
    │
    ├─ android.app.KeyguardManager$1 instance
    │    Leaking: UNKNOWN
    │    Anonymous subclass of com.android.internal.policy.IKeyguardDismissCallback$Stub
    │    ↓ KeyguardManager$1.val$activity
    │                        ~~~~~~~~~~~~
    ╰→ com.example.myapplication.MainActivity instance
    ​     Leaking: YES (ObjectWatcher was watching this because com.example.myapplication.MainActivity received Activity#onDestroy() callback and Activity#mDestroyed is true)
    ​     

1 Ответ

3 голосов
/ 02 марта 2020

Утечка указывает, что в собственном коде есть глобальная переменная, которая хранит ссылку на экземпляр KeyguardManager$1, который реализует com.android.internal.policy.IKeyguardDismissCallback$Stub, а KeyguardManager$1 сама содержит ссылку на действие.

Источники реализации KeyguardManager # requestDismissKeyguard можно найти здесь: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/KeyguardManager.java#574:

ActivityTaskManager.getService().dismissKeyguard(
        activity.getActivityToken(), new IKeyguardDismissCallback.Stub() {
    @Override
    public void onDismissError() throws RemoteException {
        if (callback != null && !activity.isDestroyed()) {
            activity.mHandler.post(callback::onDismissError);
        }
    }
    @Override
    public void onDismissSucceeded() throws RemoteException {
        if (callback != null && !activity.isDestroyed()) {
            activity.mHandler.post(callback::onDismissSucceeded);
        }
    }
    @Override
    public void onDismissCancelled() throws RemoteException {
        if (callback != null && !activity.isDestroyed()) {
            activity.mHandler.post(callback::onDismissCancelled);
        }
    }
}, message);

Это межпроцессный вызов для процесса службы ActivityTaskManager. Заглушки, которые настроены на получение результата при обратном вызове процесса службы ActivityTaskManager, содержат ссылку на действие. К сожалению, собственные заглушки, как правило, хранятся в памяти дольше, чем ожидалось, поскольку они зависят от G C, запущенного в другом процессе.

Это явно ошибка в инфраструктуре Android. Вы должны сообщить об ошибке в инфраструктуру Android и предоставить пример приложения, которое ее воспроизводит.

...