调用AdView.loadAd触发ANR是否为Google play-services库相关问题?
问题根因分析
- 从提供的主线程堆栈可以明确,本次ANR是主线程调用
AdView.loadAd()时发生阻塞导致:主线程正在等待com.google.android.gms.dynamite.DynamiteModule的类锁,该锁此时被编号14的后台线程持有,阻塞超时后触发ANR。 - 这是
play-services-ads-lite:20.2.0配套play-services-basement:17.6.0版本的已知问题,DynamiteModule的初始化逻辑类锁粒度过大,在应用冷启动同时触发广告加载、Google Play服务后台校验/更新的场景下,很容易出现锁竞争。
可落地的解决方案
- 优先升级AdMob SDK版本:将
play-services-ads依赖升级到21.0.0及以上版本,Google官方在后续版本中已经优化了DynamiteModule的锁逻辑,这类锁竞争导致的ANR出现概率会大幅降低。 - 调整广告加载时机:如果暂时无法升级SDK,不要在
Activity.onCreate()生命周期中同步调用loadAd(),可以等Activity首帧渲染完成后延迟100~300ms再触发广告加载,避开冷启动阶段的资源抢占高峰,减少锁竞争概率。注意loadAd()仍需在主线程调用,不要切到子线程执行,避免触发官方规则限制的其他异常。 - 排查额外锁竞争点:检查项目中是否有其他业务主动调用了DynamiteModule相关API,如果有可以将这部分逻辑放到子线程执行,避免和广告初始化逻辑争抢类锁。
内容的提问来源于stack exchange,提问作者t0m
相关产品推荐
相关产品推荐

