升级play-services-location至21.0.1引发ANR问题求助
我近期将Android项目升级至Android 33,并把com.google.android.gms:play-services-location从20.0.0版本更新到21.0.1。项目编译无异常,但打开应用内的手机号查询页面(PhoneLookupActivity)时,屏幕冻结并触发ANR错误,回退到20.0.0版本后一切恢复正常。问题与页面内手机号输入框的焦点请求功能直接相关。
相关配置信息
项目级Gradle配置
dependencies { classpath 'com.android.tools.build:gradle:8.1.0' classpath "com.google.gms:google-services:4.3.15" classpath "com.google.firebase:firebase-crashlytics-gradle:2.9.8" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "com.google.firebase:firebase-appdistribution-gradle:4.0.0" classpath "org.jetbrains.kotlin:kotlin-serialization:1.6.0" classpath 'com.google.firebase:perf-plugin:1.4.2' }
模块级依赖(问题版本为21.0.1)
playServiceAuth : "com.google.android.gms:play-services-auth:20.6.0", playServiceApiPhone : "com.google.android.gms:play-services-auth-api-phone:18.0.1", playServiceAnalytics : "com.google.android.gms:play-services-analytics:18.0.3", playServiceBase : "com.google.android.gms:play-services-base:18.2.0", playServiceLocation : "com.google.android.gms:play-services-location:21.0.1", // 触发ANR的版本 playServiceMaps : "com.google.android.gms:play-services-maps:18.1.0",
使用Firebase BOM版本:30.5.0
ANR错误日志
ANR in com.app.android.debug (com.app.android.debug/com.app.android.view.ui.activities.PhoneLookupActivity) PID: 29822 Reason: Input dispatching timed out (63037a6 com.app.android.debug/com.app.android.view.ui.activities.PhoneLookupActivity (server) is not responding. Waited 10010ms for FocusEvent(hasFocus=true)) Parent: com.app.android.debug/com.app.android.view.ui.activities.PhoneLookupActivity ErrorId: c4a725b2-2ec6-470d-91c9-926796d612d5 Frozen: s[false] g[false]
可能的原因与解决方法
1. 权限请求阻塞UI线程
play-services-location 21.x对Android 13+的权限处理逻辑有变更,若在UI线程同步请求位置权限(如ACCESS_FINE_LOCATION),会直接阻塞UI导致ANR。
解决方式:
将权限请求移至后台线程执行,比如使用协程:
lifecycleScope.launch(Dispatchers.IO) { val permissionResult = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { results -> // 处理权限结果 }.launch(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)) }
2. Location API同步调用占用UI线程
21.x版本部分Location API的内部实现改为同步逻辑,若在UI线程直接调用FusedLocationProviderClient的同步方法,会引发线程阻塞。
解决方式:
确保所有Location相关操作在后台线程执行,使用异步回调或挂起函数:
lifecycleScope.launch(Dispatchers.IO) { val location = fusedLocationProviderClient.lastLocation.await() // 处理位置数据 }
3. 依赖版本不兼容
play-services-location 21.x需要更高版本的play-services-base等基础依赖,当前18.2.0的版本过低,可能引发内部死锁或逻辑冲突。
解决方式:
升级相关依赖到兼容版本:
playServiceAuth : "com.google.android.gms:play-services-auth:20.6.0", playServiceApiPhone : "com.google.android.gms:play-services-auth-api-phone:18.1.0", playServiceBase : "com.google.android.gms:play-services-base:18.3.0", playServiceLocation : "com.google.android.gms:play-services-location:21.0.1",
4. 焦点请求与Location初始化冲突
输入框的requestFocus()操作若与Location服务初始化在UI线程同时执行,21.x版本的Location初始化耗时增加会阻塞焦点事件分发。
解决方式:
延迟焦点请求,等待Location初始化完成后再执行:
lifecycleScope.launch { delay(100) // 短延迟避开初始化高峰 phoneInputEditText.requestFocus() }
内容的提问来源于stack exchange,提问作者dicarlomagnus

