仅在运行 Android 12 的 Pixel 设备上出现 CannotDeliverBroadcastException

2024-04-18

我发现 Crashlytics 发生了崩溃,但我无法重现或找到其原因。该崩溃仅发生在运行 Android 12 的 Google Pixel 设备上,并且崩溃始终发生在后台。

这是来自 Crashlytics 的崩溃日志:

Fatal Exception: android.app.RemoteServiceException$CannotDeliverBroadcastException: can't deliver broadcast
   at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:1939)
   at android.app.ActivityThread.access$2700(ActivityThread.java:256)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2190)
   at android.os.Handler.dispatchMessage(Handler.java:106)
   at android.os.Looper.loopOnce(Looper.java:201)
   at android.os.Looper.loop(Looper.java:288)
   at android.app.ActivityThread.main(ActivityThread.java:7870)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

我看过类似的问题(比如this https://stackoverflow.com/questions/50681356/android-app-crashes-with-android-app-remoteserviceexception-cant-deliver-broa and this https://stackoverflow.com/questions/46971153/fatal-exception-android-app-remoteserviceexception-cant-deliver-broadcast-at)但是 Crashlytics 显示这些用户都有足够的可用内存,并且我们的代码库中没有任何地方可以调用registerReceiver or sendBroadcast所以第二个问题的解决方案没有任何帮助。

根据有限的日志,我很确定当用户收到推送通知时会发生崩溃,但我有一台运行 Android 12 的 Google Pixel 4a,在向自己发送通知时根本无法重现它。

我们有一个习俗FirebaseMessagingService监听我们在清单中注册的通知和一些BroadcastReceiver监听地理围栏更新并利用WorkManager当检测到转换时做一些工作。最近唯一改变的是我们更新了WorkManager使用初始化自身Android的应用程序启动库 https://developer.android.com/topic/libraries/app-startup,但我不确定这是否相关,因为崩溃日志没有给我任何信息,而且如果我们的实现存在问题,它也不会仅限于运行 Android 12 的 Pixel 设备。

有人以前见过这个吗?或者运行 Android 12 的 Pixel 设备上是否存在专门的错误?我花了几个小时深入研究这个问题,但完全不知所措。


关于 Android 13,而不是 12 上的早期问题,存在 Google 跟踪器问题here https://issuetracker.google.com/issues/245258072,在撰写本文时已分配但正在等待有意义的响应。

该问题的摘要是,它仅发生在 13 上,并且仅发生在 Pixel 设备上。

CommonsWare 有一篇关于此的博客文章here https://commonsware.com/blog/2022/10/16/issue-trackers-cant-deliver-broadcast-bug.html,我在任何地方找到的唯一其他线索是在 GrapheneOS 的变更日志中,here https://grapheneos.org/releases#2022092800,其中有此行条目:

沙盒化 Google Play 兼容层:不向用户报告 CannotDeliverBroadcastException

我们使用这个 Play 库并遇到了这个错误,因此 Graphene 可能遇到了这个问题,并且不得不进行操作系统修复。

Update:

我暂时相信我们作为一个应用程序已经抑制了这个问题,并阻止它污染我们的统计数据。

我们设置了一个异常处理程序来吸收它,这就是 GrapheneOS 正在做的事情——归功于他们。

class CustomUncaughtExceptionHandler(
    private val uncaughtExceptionHandler: Thread.UncaughtExceptionHandler) : Thread.UncaughtExceptionHandler {

    override fun uncaughtException(thread: Thread, exception: Throwable) {
        if (shouldAbsorb(exception)) {
            return
        }
        uncaughtExceptionHandler.uncaughtException(thread, exception)
    }

    /**
     * Evaluate whether to silently absorb uncaught crashes such that they
     * don't crash the app. We generally want to avoid this practice - we would
     * rather know about them. However in some cases there's nothing we can do
     * about the crash (e.g. it is an OS fault) and we would rather not have them
     * pollute our reliability stats.
     */
    private fun shouldAbsorb(exception: Throwable): Boolean {
        return when (exception::class.simpleName) {

            "CannotDeliverBroadcastException" -> true

            else -> false
        }
    }
}

我们必须对类名字符串进行操作,因为 CannotDeliverBroadcastException 类是隐藏的,我们无法使用。

我们在 Application.onCreate() 方法的早期安装这个处理程序,如下所示:

val defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler()
Thread.setDefaultUncaughtExceptionHandler(
    CustomUncaughtExceptionHandler(defaultUncaughtExceptionHandler)
)

我对此可能有点不成熟,但到目前为止,这还没有导致 Play 管理中心中出现任何崩溃。有一些确实出现在我们的其他报告平台中,其中报告的内容/未报告的内容始终各不相同。

需要明确的是,我并不是说这是一种好方法,或者您必须采取的方法。它需要客户端版本,并且有掩盖与此根本原因无关的异常的风险。 Google 有责任在收集数据时解决或忽略此问题。然而,它似乎已经停止了对我们标题可靠性统计数据的影响,所以我想我会分享它作为一种可能性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

仅在运行 Android 12 的 Pixel 设备上出现 CannotDeliverBroadcastException 的相关文章

随机推荐