java - 取消注册在 Activity 上下文中注册的 BroadcastReceiver 会导致 IllegalArgumentException 崩溃
问题描述
坠机是非常奇怪的一次。
在onStart
中,注册了存储在 Activity 字段中的 BroadcastReceiver。在onStop
中,此 BroadcastReceiver 未注册。当 BroadcastReceiver 注册成功后,我也设置了isRegistered
fieldtrue
为
但是,在 Crashlytics 中,我看到有时这会失败,并且整个应用程序因消息而崩溃IllegalArgumentException
,Receiver not registered
该消息源自android.app.LoadedApk#forgetReceiverDispatcher
. 考虑到我检查了标志,这很奇怪,对吧?
在我查看了处理注册/注销ContextImpl
的LoadedApk
类并添加了一些基于反射的诊断之后,它变得更加神秘。简而言之,在每次这样的崩溃中,我都会提取现有的映射Context
到BroadcastReceiver
(参见ContextImpl.java:1590和LoadedApk.java:1361)。
当它正常注销时,没有崩溃,我可以看到这样的地图:
com.mypackage.myapp.MyAppContext instance -> list of instances that are registered app wide
com.mypackage.myapp.MyActivity1 instance -> list of instances that are registered for Activity1
com.mypackage.myapp.MyActivity2 instance -> list of instances that are registered for Activity2
...
但是,如果发生崩溃,此地图将如下所示:
com.mypackage.myapp.MyAppContext instance -> list of instances that are registered app wide
即没有我BroadcastReceiver
注册的活动,即使我从未打过电话unregisterReceiver
!
它只发生在一个特定的活动中,所以我的第一个猜测是这个活动以某种方式泄漏,onDestroy
生命周期被调用,活动条目从接收者映射中删除,然后当我们尝试注销它时显然接收者不会在那里。但是,如果是这样的话,为什么在那onStop
之后被调用onDestroy
呢?为什么接收者列表完全是空的?
如果不是泄漏,那么什么会导致这种令人费解的行为呢?我真的希望其他人经历过这样的奇怪事件,并且可以帮助我,因为现在我完全没有想法。
解决方案
已编辑
只能说我感受到了痛苦。为了我自己的问题,我刚刚找到了一个解决方法,但是,为了回答你的问题,我真的深入研究了文档,所以更老的问题甚至写了简单的代码并自己检查了一些生命周期测试(虽然我已经找到了答案我错了)。我找不到此事件发生的原因,但要修复它,我建议将 register/unRegister 包装在 try catch 块中:
private void registerBroadcastReceiver() {
try {
appUpdateReceiver = new AppUpdateReceiver();
registerReceiver(appUpdateReceiver, appUpdateIntentFilter);
} catch (IllegalArgumentException e) {
// already registered
}
}
private void unRegisterBroadCastReceiver() {
try {
unregisterReceiver(appUpdateReceiver);
} catch (IllegalArgumentException e) {
// already unregistered
}
}
请提供一些代码,以便社区可以更深入地研究这个问题。并感谢您提到 LoadedApk 类。
推荐阅读
- postgresql - PostgreSql 用户没有发现任何关系
- asp.net - HttpRequestMessage.GetClientCertificate() 在 ASP Web API DelegatingHandler 中返回 null
- javascript - react-d3-graph 设置节点的起始位置
- libreoffice - Libreoffice:斜体中断(替换功能混乱)
- ios - 快速获取并检查内部(本地)JSON文件
- sql - 如何在 T SQL 中旋转数字列?
- excel - 从 .vbs 文件中杀死特定的 Excel.exe
- python - Python,语音识别卡在“正在听...”
- angular - 注销时清除可观察值
- laravel - 在 laravel 中获取数据库数据到前视图?