android - KeyguardManager 内存泄漏
问题描述
活动完成后,我正在使用此代码 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)
解决方案
泄漏跟踪表明本机代码中存在一个全局变量,该变量保留了对KeyguardManager$1
implements的实例的引用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 服务进程回调时接收结果的存根持有对活动的引用。不幸的是,本机存根在内存中的保存时间往往比预期的要长,因为它们依赖于在其他进程中运行的 GC。
这显然是 Android 框架中的一个错误。您应该向 Android 框架提交错误并提供重现该错误的示例应用程序。
推荐阅读
- javascript - 如何将字体加载到反应项目中
- bootstrap-vue - 如何使用 bootstrap-vue 中可用的“关闭”功能
- google-drive-api - Google Drive API - 是否可以获取相对于共享路径的文件?
- android - 选择器(Native Base)中的 defaultValue 无法正常工作
- firebase - Flutter Firebase authStateChanges() with Provider & NullSafety On
- javascript - Phaser:使用 Arcade 物理和 Matter 检测自定义碰撞形状(由 Tiled 中的 tile 碰撞编辑器制作)
- python - pythonpath 在 Powershell 中工作,但在 Ubuntu 中不工作
- jquery - 在第 7 代 iPad 上获取 2 个智能应用横幅
- snakemake - 缺少所有规则的输入文件,但应该存在
- javascript - 等待ajax数据加载