App启动调用MobileAds.initialize()触发Binder事务等待ANR求助
应用启动ANR问题:MobileAds.initialize()导致主线程Binder事务等待
问题描述
应用在部分设备启动时触发ANR,Crashlytics捕获的报告显示,ANR由主线程等待Binder事务引发,根源是App.onCreate()中的MobileAds.initialize()调用。
崩溃堆栈
main (native):tid=1 systid=29049 #00 pc 0x4b50c libc.so (syscall + 28) #01 pc 0x1b07a4 libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*) + 148) #02 pc 0x673d78 libart.so (art::GoToRunnable(art::Thread*) + 480) #03 pc 0x673b54 libart.so (art::JniMethodEnd(unsigned int, art::Thread*) + 28) at android.os.BinderProxy.transactNative(Native method) at android.os.BinderProxy.transact(BinderProxy.java:540) at android.content.ContentProviderProxy.call(ContentProviderNative.java:730) at android.provider.Settings$NameValueCache.getStringForUser(Settings.java:2769) at android.provider.Settings$System.getStringForUser(Settings.java:3204) at android.provider.Settings$System.getIntForUser(Settings.java:3303) at android.provider.Settings$System.getInt(Settings.java:3297) at org.chromium.ui.accessibility.AccessibilityState.a(chromium-TrichromeWebViewGoogle.aab-stable-573519631:193) at org.chromium.ui.accessibility.AccessibilityState.registerObservers(chromium-TrichromeWebViewGoogle.aab-stable-573519631:87) at J.N.M1Y_XVCN(Native method) at org.chromium.content.browser.BrowserStartupControllerImpl.a(chromium-TrichromeWebViewGoogle.aab-stable-573519631:10) at org.chromium.content.browser.BrowserStartupControllerImpl.f(chromium-TrichromeWebViewGoogle.aab-stable-573519631:67) at E9.run(chromium-TrichromeWebViewGoogle.aab-stable-573519631:111) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.chromium.base.task.PostTask.d(chromium-TrichromeWebViewGoogle.aab-stable-573519631:11) at org.chromium.android_webview.AwBrowserProcess.k(chromium-TrichromeWebViewGoogle.aab-stable-573519631:34) at com.android.webview.chromium.M.d(chromium-TrichromeWebViewGoogle.aab-stable-573519631:183) at com.android.webview.chromium.M.b(chromium-TrichromeWebViewGoogle.aab-stable-573519631:42) at com.android.webview.chromium.WebViewChromiumFactoryProvider.k(chromium-TrichromeWebViewGoogle.aab-stable-573519631:11) at com.android.webview.chromium.WebViewChromium.init(chromium-TrichromeWebViewGoogle.aab-stable-573519631:94) at android.webkit.WebView.<init>(WebView.java:435) at android.webkit.WebView.<init>(WebView.java:355) at android.webkit.WebView.<init>(WebView.java:337) at android.webkit.WebView.<init>(WebView.java:324) at android.webkit.WebView.<init>(WebView.java:314) at com.google.android.gms.ads.internal.webview.ac.<init>(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554:1) at com.google.android.gms.ads.internal.webview.r.a(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554:4) at com.google.android.gms.ads.internal.webview.v.a(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554:4) at com.google.android.gms.ads.internal.js.k.<init>(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554:3) at com.google.android.gms.ads.internal.js.q.run(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554:5) at com.google.android.gms.ads.internal.util.future.c.execute(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554:2) at com.google.android.gms.ads.internal.util.future.d.execute(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554) at com.google.android.gms.ads.internal.js.ah.b(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554:3) at com.google.android.gms.ads.internal.js.ah.a(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554:5) at com.google.android.gms.ads.internal.js.function.n.b(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554) at com.google.android.gms.ads.internal.e.b(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554:20) at com.google.android.gms.ads.internal.e.a(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554) at com.google.android.gms.ads.nonagon.az.i(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554:8) at com.google.android.gms.ads.internal.client.bu.bN(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554:34) at agb.onTransact(:com.google.android.gms.policy_ads_fdr_dynamite@231710101@231710100057.526733554.526733554:4) at android.os.Binder.transact(Binder.java:1043) at com.google.android.gms.internal.ads.zzato.zzbh(com.google.android.gms:play-services-ads-base@@22.2.0:2) at com.google.android.gms.ads.internal.client.zzcm.zzl(com.google.android.gms:play-services-ads-lite@@22.2.0:4) at com.google.android.gms.ads.internal.client.zzej.zzz(com.google.android.gms:play-services-ads-lite@@22.2.0:4) at com.google.android.gms.ads.internal.client.zzej.zzn(zzej.java:23) at com.google.android.gms.ads.MobileAds.initialize(com.google.android.gms:play-services-ads-lite@@22.2.0:3) at com.pn.namewallpaper.App.onCreate(App.kt:54) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1192) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6756) at android.app.ActivityThread.access$1400(ActivityThread.java:244) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1952) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7703) at java.lang.reflect.Method.invoke(Native method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:997)
相关代码片段(App.kt)
override fun onCreate() { super.onCreate() try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { val process = getProcessName() if (packageName != process) { WebView.setDataDirectorySuffix(process) WebView(this) } } } catch (e: Exception) { e.printStackTrace() } try { MobileAds.initialize(this) { } if (BuildConfig.DEBUG) MobileAds.setRequestConfiguration( RequestConfiguration.Builder() .setTestDeviceIds(listOf("E80042EF1278636536D6C76694C9515C")).build() ) appOpenManager = AppOpenManager(this) } catch (e: Exception) { e.printStackTrace() } }
问题分析
从堆栈轨迹可以看出:
MobileAds.initialize()内部会初始化WebView组件- WebView初始化过程中调用
Settings.System.getInt()时触发Binder事务,主线程因等待该事务完成被阻塞 - 广告初始化逻辑直接在Application的
onCreate()主线程执行,进一步加重了启动阶段的主线程负载,最终触发ANR
解决方案
1. 将广告初始化移至后台线程
避免主线程同步执行耗时的广告初始化操作,使用协程或线程池将逻辑放到后台:
协程实现示例
override fun onCreate() { super.onCreate() try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { val process = getProcessName() if (packageName != process) { WebView.setDataDirectorySuffix(process) WebView(this) } } } catch (e: Exception) { e.printStackTrace() } // 后台线程执行广告初始化 CoroutineScope(Dispatchers.IO).launch { try { MobileAds.initialize(this@App) { } if (BuildConfig.DEBUG) { MobileAds.setRequestConfiguration( RequestConfiguration.Builder() .setTestDeviceIds(listOf("E80042EF1278636536D6C76694C9515C")).build() ) } // 切回主线程初始化AppOpenManager(若依赖主线程环境) withContext(Dispatchers.Main) { appOpenManager = AppOpenManager(this@App) } } catch (e: Exception) { e.printStackTrace() } } }
线程池实现示例
override fun onCreate() { super.onCreate() try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { val process = getProcessName() if (packageName != process) { WebView.setDataDirectorySuffix(process) WebView(this) } } } catch (e: Exception) { e.printStackTrace() } Executors.newSingleThreadExecutor().execute { try { MobileAds.initialize(this@App) { } if (BuildConfig.DEBUG) { MobileAds.setRequestConfiguration( RequestConfiguration.Builder() .setTestDeviceIds(listOf("E80042EF1278636536D6C76694C9515C")).build() ) } // 切回主线程初始化AppOpenManager runOnUiThread { appOpenManager = AppOpenManager(this@App) } } catch (e: Exception) { e.printStackTrace() } } }
2. 延迟广告初始化
可以等到应用启动完成后(比如第一个Activity的onResume方法)再执行广告初始化,避免在Application启动阶段抢占主线程资源。
3. 优化WebView初始化
如果必须提前初始化WebView,确保相关操作不在主线程阻塞,或者提前完成多进程WebView的配置(如代码中已处理Android P+的多进程数据目录)。
注意事项
AppOpenManager若依赖主线程环境,必须切回主线程初始化- 广告初始化完成前请求广告可能失败,需在初始化回调中处理广告加载逻辑
内容的提问来源于stack exchange,提问作者Pratik
相关产品推荐
相关产品推荐

