咨询:AAssetManager_open在Android 8.1设备上死锁的原因及复现方式
AAssetManager_open Deadlock on Android 8.1 + AdMob Mediation 根据我处理Android原生及AdMob Mediation相关问题的经验,确实存在几个已知的场景会导致Android 8.1环境下AAssetManager_open触发互斥体阻塞死锁,尤其是结合AdMob Mediation的情况:
Third-party AdMob Mediation SDK Resource Loading Conflicts
部分AdMob Mediation合作方的SDK在初始化或广告加载流程中,会在后台线程调用AssetManager相关接口(比如加载广告素材、配置文件)。在Android 8.1上,这些线程的资源操作可能和主线程的AAssetManager_open请求形成互斥体竞争:如果第三方SDK的线程持有AssetManager互斥体后,因网络IO等待、其他锁阻塞等原因未及时释放,主线程的AAssetManager_open调用就会一直等待,最终触发ANR。这类问题通常是SDK的兼容性bug,不同设备触发时机不同是因为线程调度的不确定性。Android 8.1 AssetManager Race Condition
虽然Android 8.1的AssetManager互斥体逻辑看起来简单,但存在一个容易被忽略的竞态条件:当主线程调用AAssetManager_open加载资源时,若有其他线程(比如AdMob Mediation的广告加载线程)同时调用AssetManager.addAssetPath或其他修改AssetManager状态的方法,就可能形成互斥体等待链。AAssetManager_open会持有AssetManager的核心互斥体,而状态修改类操作同样需要该互斥体;如果第三方SDK的线程在持有互斥体时因外部依赖(比如等待广告素材下载)挂起,主线程就会陷入无限等待。Obfuscation/Resource Packaging Path Resolution Issues
开启R8/ProGuard混淆或使用自定义资源打包工具时,可能导致AssetManager无法正确解析资源路径。在AdMob Mediation环境下,广告SDK通常会加载自身的assets资源,若路径解析异常,AAssetManager_open会进入异常的资源查找循环,长时间持有互斥体不释放,进而阻塞主线程的请求。
Additional Suggestions
- 优先升级AdMob Mediation SDK及所有合作方SDK到最新版本——Google和第三方厂商通常会针对Android 8.1这类特定版本的兼容性问题发布修复补丁。
- 逐个移除接入的第三方Mediation SDK,测试是否还会出现死锁,定位到具体的冲突SDK后,联系厂商获取修复方案或临时规避措施。
- 虽然将主线程的AssetManager操作移到非主线程能规避ANR,但可以给非主线程的调用添加超时逻辑,避免线程无意义挂起。
内容的提问来源于stack exchange,提问作者ajso

