ParcelFileDescriptor 泄漏发生在哪里?

Bob*_*der 5 android android-backup-service android-strictmode

我已经按照数据备份指南实现了BackupAgent。代码的行为符合预期,直到设置为检测泄漏的可关闭对象。执行备份并发生 GC 后,CloseGuard 报告泄漏并显示以下堆栈跟踪:StrictMode.VmPolicyParcelFileDescriptor

\n\n
06-28 21:47:39.683  25072-25081/com.qbix.nub E/StrictMode\xef\xb9\x95 A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.\n    java.lang.Throwable: Explicit termination method \'close\' not called\n            at dalvik.system.CloseGuard.open(CloseGuard.java:184)\n            at android.os.ParcelFileDescriptor.<init>(ParcelFileDescriptor.java:179)\n            at android.os.ParcelFileDescriptor$1.createFromParcel(ParcelFileDescriptor.java:905)\n            at android.os.ParcelFileDescriptor$1.createFromParcel(ParcelFileDescriptor.java:897)\n            at android.app.IBackupAgent$Stub.onTransact(IBackupAgent.java:64)\n            at android.os.Binder.execTransact(Binder.java:404)\n            at dalvik.system.NativeStart.run(Native Method)\n06-28 21:47:39.683  25072-25081/com.qbix.nub W/System.err\xef\xb9\x95 StrictMode VmPolicy violation with POLICY_DEATH; shutting down.\n06-28 21:47:39.683  25072-25081/com.qbix.nub I/Process\xef\xb9\x95 Sending signal. PID: 25072 SIG: 9\n
Run Code Online (Sandbox Code Playgroud)\n\n

为了确认我没有泄漏ParcelFileDescriptor我的BackupAgent,我onBackup()像这样存根:

\n\n
@Override\npublic void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) throws IOException {\n    if (oldState != null) {\n        oldState.close();\n    }\n    newState.close();\n    return;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

此更改并未修复泄漏问题。

\n\n

这些是我用来重现问题的步骤:

\n\n
    \n
  1. 修改应用程序数据以触发调用BackupManager.dataChanged()
  2. \n
  3. 用于adb shell bmgr run强制执行备份操作
  4. \n
  5. 启动 GC 从Android Studio
  6. \n
\n\n

我对绑定服务了解不够,无法了解堆栈跟踪是否提供了有关泄漏是在系统中BackupService还是由我无法看到的代码中的错误引起的线索。当使用存根运行时,泄漏的持续发生onBackup()表明泄漏发生在服务中。

\n\n

在研究这个问题时,我发现过去几个月发布的其他问题在其以下内容中包含相同的泄漏报告logcats

\n\n

Android 中的资源泄漏

\n\n

Android 中的导航抽屉出现问题

\n\n

Android - HTTP Get - 显式终止未调用错误。我缺少什么?

\n\n

解决 android 中的 java.lang.Throwable 异常

\n\n

上面显示的 logcat 来自 KitKat 设备。在另一台运行 Lollipop 的设备上,我认为发生了同样的错误。应用程序被终止,但 logcat 不包含 CloseGuard 转储。不知道我需要做什么才能看到这一点。

\n