Firebase Strictmode 资源泄漏

SKO*_*son 5 resource-leak firebase crashlytics

在通过 Fabric 从 Crashlytics 转换为通过 Firebase 的 Crashlytics 之后,我开始在调试运行中看到以下调用堆栈,其中启用了 StrictMode 以查找资源泄漏。

StrictMode 与此代码一起使用,仅在调试版本中使用:

StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
    .detectLeakedClosableObjects()
    .penaltyLog()
    .build());
Run Code Online (Sandbox Code Playgroud)

我在项目级 gradle 中使用了这个版本的 Fabric 的 gradle 工具:

classpath "io.fabric.tools:gradle:1.27.0"
Run Code Online (Sandbox Code Playgroud)

以及模块级 gradle 中这些版本的 Firebase 和 Crashlytics:

implementation "com.google.firebase:firebase-core:16.0.7"
implementation "com.crashlytics.sdk.android:crashlytics:2.9.8"
Run Code Online (Sandbox Code Playgroud)

在初始化期间,Firebase 检测会启动一个后台线程,该线程使用 okhttp 进行设置调用。当它发生时, StrictMode 会导致此调用堆栈弹出:

W/CrashlyticsCore: Received null settings, skipping report submission!
D/StrictMode: StrictMode policy violation: android.os.strictmode.LeakedClosableViolation: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
        at android.os.StrictMode$AndroidCloseGuardReporter.report(StrictMode.java:1786)
        at dalvik.system.CloseGuard.warnIfOpen(CloseGuard.java:264)
        at java.util.zip.Inflater.finalize(Inflater.java:398)
        at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:250)
        at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:237)
        at java.lang.Daemons$Daemon.run(Daemons.java:103)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: java.lang.Throwable: Explicit termination method 'end' not called
        at dalvik.system.CloseGuard.open(CloseGuard.java:221)
        at java.util.zip.Inflater.<init>(Inflater.java:114)
        at com.android.okhttp.okio.GzipSource.<init>(GzipSource.java:62)
        at com.android.okhttp.internal.http.HttpEngine.unzip(HttpEngine.java:473)
        at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:648)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:471)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:538)
        at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
        at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:26)
        at io.fabric.sdk.android.services.network.HttpRequest.code(HttpRequest.java:1357)
        at io.fabric.sdk.android.services.settings.DefaultSettingsSpiCall.handleResponse(DefaultSettingsSpiCall.java:104)
        at io.fabric.sdk.android.services.settings.DefaultSettingsSpiCall.invoke(DefaultSettingsSpiCall.java:88)
        at io.fabric.sdk.android.services.settings.DefaultSettingsController.loadSettingsData(DefaultSettingsController.java:90)
        at io.fabric.sdk.android.services.settings.DefaultSettingsController.loadSettingsData(DefaultSettingsController.java:67)
        at io.fabric.sdk.android.services.settings.Settings.loadSettingsData(Settings.java:153)
        at io.fabric.sdk.android.Onboarding.retrieveSettingsData(Onboarding.java:126)
        at io.fabric.sdk.android.Onboarding.doInBackground(Onboarding.java:99)
        at io.fabric.sdk.android.Onboarding.doInBackground(Onboarding.java:45)
        at io.fabric.sdk.android.InitializationTask.doInBackground(InitializationTask.java:63)
        at io.fabric.sdk.android.InitializationTask.doInBackground(InitializationTask.java:28)
        at io.fabric.sdk.android.services.concurrency.AsyncTask$2.call(AsyncTask.java:311)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764) 
D/FA: Event not sent since app measurement is disabled
Run Code Online (Sandbox Code Playgroud)

在应用程序的初始活动启动期间,我几乎在我的应用程序的每次调试运行中都看到了这种情况。然而,支持声称他们没有看到这一点。

有谁知道是什么条件导致 Fabric 启动这个入职/设置线程?

我在这些其他帖子中看到过类似的 StrictMode 调用堆栈。我不知道这个泄漏是在 Fabric 代码中,还是在他们使用的 okhttp 库中。以下是类似案例的链接,在这些案例中,人们看到了在我看来与相同的潜在资源泄漏类似的情况:

StrictMode 惩罚 Firebase 广告

启用 StrictMode(检测全部)的 Crashlytics 给出“检测到未标记的套接字”

https://github.com/cloudant/sync-android/issues/577