升级Google库与targetSDKVersion32后ContentResolver出现ANR求助
升级谷歌库与targetSDKVersion到32后ContentResolver相关ANR排查求助
升级所有谷歌外部库并将targetSDKVersion设置为32后,应用在Firebase Crashlytics中出现大量ContentResolver相关ANR。未修改任何业务代码,怀疑是AndroidX或Android SDK 32中ContentResolver或查询逻辑的后台变更导致。
案例1:ContentResolver查询计数触发ANR
对应堆栈信息:
main (native): tid=1 systid=14120 #00 pc 0x4f55c libc.so (syscall + 28) #01 pc 0x47cc80 libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*) + 140) #02 pc 0x75b88c libart.so (artJniMethodEnd + 204) #03 pc 0x20facc libart.so (art_jni_method_end + 12) at android.os.BinderProxy.transactNative(BinderProxy.java) at android.os.BinderProxy.transact(BinderProxy.java:584) at android.content.IContentService$Stub$Proxy.unregisterContentObserver(IContentService.java:1005) at android.content.ContentResolver.unregisterContentObserver(ContentResolver.java:2730) at android.database.AbstractCursor.onDeactivateOrClose(AbstractCursor.java:157) at android.database.AbstractWindowedCursor.onDeactivateOrClose(AbstractWindowedCursor.java:213) at android.database.AbstractCursor.close(AbstractCursor.java:186) at android.database.sqlite.SQLiteCursor.close(SQLiteCursor.java:207) at android.database.CursorWrapper.close(CursorWrapper.java:54) at android.content.ContentResolver$CursorWrapperInner.close(ContentResolver.java:3870) at com.xxxx.xxx.db.xxxDatabase.getxxxsCount(xxxDatabase.java:1470) at com.xxxx.xxx.db.xxxDatabase.getFiredOffxxxsCount(xxxDatabase.java:1361) at com.xxxx.xxx.utilities.xxxNotification.shouldGroup(xxxNotification.java:999) at com.xxxx.xxx.utilities.xxxNotification.getNotification(xxxNotification.java:720) at com.xxxx.xxx.utilities.xxxNotification.buildNotification(xxxNotification.java:522) at com.xxxx.xxx.utilities.xxxNotification.buildNotification(xxxNotification.java:451) at com.xxxx.xxx.utilities.xxxNotification.updateNotificationGroup(xxxNotification.java:1318) at com.xxxx.xxx.utilities.xxxNotification.cancelNotification(xxxNotification.java:335) at com.xxxx.xxx.utilities.xxxNotification.snooze(xxxNotification.java:1915) at com.xxxx.xxx.AlarmList.snoozeAllNewAlarmTime(AlarmList.java:80) at com.xxxx.xxx.AlarmList.onFinishSnoozeDialog(AlarmList.java:117) at com.xxxx.xxx.dialogs.SnoozeDialog.onClick(SnoozeDialog.java:279) at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167) 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:7898) 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:936)
案例2:无业务代码关联的ANR
有时还会出现不涉及自身应用类的ANR,堆栈信息如下:
main (native): tid=1 systid=9452 #00 pc 0xd6a94 libc.so (__ioctl + 4) #01 pc 0x935c4 libc.so (ioctl + 156) #02 pc 0x51a7c libbinder.so (android::IPCThreadState::talkWithDriver(bool) + 296) #03 pc 0x52a68 libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*) + 60) #04 pc 0x527d8 libbinder.so (android::IPCThreadState::transact(int, unsigned int, android::Parcel const&, android::Parcel*, unsigned int) + 184) #05 pc 0x4b01c libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int) + 188) #06 pc 0x12b3e8 libandroid_runtime.so (android_os_BinderProxy_transact(_JNIEnv*, _jobject*, int, _jobject*, _jobject*, int) + 152) at android.os.BinderProxy.transactNative(BinderProxy.java) at android.os.BinderProxy.transact(BinderProxy.java:540) at bn.h(bn.java:11) at bk.a(bk.java:3) at bm.c(bm.java) at be.d(be.java:2) at bh.handleMessage(bh.java:28) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:236) at android.app.ActivityThread.main(ActivityThread.java:8056) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
排查方向建议
- 主线程操作迁移:第一个ANR的调用链显示主线程执行了ContentResolver查询、Cursor关闭(涉及Binder跨进程调用),升级后系统可能对跨进程调用的耗时或限制加强,需将所有数据库查询、ContentResolver操作移到子线程执行,比如用协程、线程池或AsyncTask。
- 谷歌库版本回退验证:逐步回退升级前的AndroidX核心库版本(如
androidx.core:core、androidx.appcompat:appcompat),观察ANR是否消失,定位到具体触发问题的库。 - SDK 32行为变更核对:查看Android 12L(SDK 32)官方文档,确认ContentResolver、Cursor或Binder相关的行为变更,比如
ContentObserver注册/注销的权限要求、跨进程调用优先级调整等,检查是否有适配遗漏。 - Cursor资源管理优化:确保所有Cursor在finally块中规范关闭,避免资源泄漏导致系统Binder调用阻塞;同时检查升级后是否系统默认给Cursor注册了更多ContentObserver,导致注销操作耗时增加。
- 系统进程状态分析:通过
adb shell dumpsys activity anr获取详细ANR报告,查看发生ANR时系统服务(如ContentService、通知服务)的负载、锁竞争情况,排查系统级阻塞原因。 - 通知逻辑优化:第一个ANR触发路径是通知构建时调用数据库查询,可缓存计数结果,避免每次构建通知都实时查询数据库,减少主线程IO操作。
内容的提问来源于stack exchange,提问作者chrisonline
相关产品推荐
相关产品推荐

