如何解决MapsInitializer.initialize引发的ANR问题?
Google MapsInitializer.initialize() 主线程调用ANR、非主线程抛异常的解决方案
问题现象
- 按官方要求在主线程调用
MapsInitializer.initialize()时,触发ANR:
ii: Application Not Responding for at least 5000 ms. at android.os.BinderProxy.transactNative(Binder.java) at android.os.BinderProxy.transact(Binder.java:511) at android.content.ContentProviderProxy.call(ContentProviderNative.java:644) at android.content.ContentResolver.call(ContentResolver.java:1447) at com.google.maps.api.android.lib6.drd.o.A(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200031.477283333.477283333:41) at com.google.maps.api.android.lib6.impl.ay.a(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200031.477283333.477283333:8) at fjj.a(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200031.477283333.477283333:1) at com.google.android.gms.maps.internal.CreatorImpl.c(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200031.477283333.477283333:35) at com.google.android.gms.maps.internal.CreatorImpl.logInitialization(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200031.477283333.477283333:1) at com.google.android.gms.maps.internal.i.bo(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200031.477283333.477283333:5) at baw.onTransact(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200031.477283333.477283333:4) at android.os.Binder.transact(Binder.java:392) at js8.A(com.google.android.gms:play-services-maps@@18.1.0:8) at h49.N0(com.google.android.gms:play-services-maps@@18.1.0:13) at q84.a(com.google.android.gms:play-services-maps@@18.1.0:99)
- 移到非主线程调用时,直接抛出异常:
java.lang.IllegalStateException: Method addObserver must be called on the main thread at xy.j(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200065.477283333.477283333:0) at xy.b(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200065.477283333.477283333:1) at com.google.android.libraries.geo.crash.monitoring.UncleanTerminationDetector.i(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200065.477283333.477283333:6) at com.google.android.gms.maps.internal.CreatorImpl.c(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200065.477283333.477283333:53) at com.google.android.gms.maps.internal.CreatorImpl.logInitialization(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200065.477283333.477283333:1) at com.google.android.gms.maps.internal.i.bm(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200065.477283333.477283333:5) at ayk.onTransact(:com.google.android.gms.policy_maps_core_dynamite@223812200@223812200065.477283333.477283333:4) at android.os.Binder.transact(Binder.java:1164) at com.google.android.gms.internal.maps.zza.zzc(com.google.android.gms:play-services-maps@@18.1.0:2) at com.google.android.gms.maps.internal.zze.zzl(com.google.android.gms:play-services-maps@@18.1.0:4) at com.google.android.gms.maps.MapsInitializer.initialize(com.google.android.gms:play-services-maps@@18.1.0:12)
原因分析
从ANR栈可以看到,MapsInitializer.initialize()内部会调用ContentProvider的跨进程方法,这个操作在主线程执行时可能因为进程间通信阻塞导致ANR;但SDK内部又有主线程校验逻辑,强制要求某些Observer操作必须在主线程完成,所以非主线程调用直接抛异常。
解决方案
采用异步初始化+主线程回调的方式,既避免主线程阻塞,又满足SDK的主线程要求:
方案1:使用官方异步API(推荐)
Google Maps SDK提供了带回调的异步初始化方法,内部自动处理线程切换:
MapsInitializer.initialize(getApplicationContext(), new OnMapsInitializedCallback() { @Override public void onMapsInitialized(@NonNull MapsInitializer.Renderer renderer) { // 初始化完成,在这里执行地图相关操作(回调在主线程) initMapView(); } });
方案2:手动线程切换(兼容旧版本)
如果使用的SDK版本无异步API,可手动在子线程执行初始化,完成后切回主线程:
new Thread(new Runnable() { @Override public void run() { try { // 子线程执行初始化的耗时部分 MapsInitializer.initialize(getApplicationContext()); // 切回主线程执行后续操作 runOnUiThread(new Runnable() { @Override public void run() { initMapView(); } }); } catch (GooglePlayServicesNotAvailableException e) { e.printStackTrace(); // 处理服务不可用情况 } } }).start();
额外优化建议
- 提前在Application启动阶段完成初始化,避免在Activity onCreate时执行导致页面卡顿;
- 升级到最新版
play-services-maps依赖,新版本可能修复了线程阻塞问题; - 若仍出现ANR,可结合
StrictMode排查主线程阻塞点,确认是否有其他耗时操作和地图初始化叠加。
内容的提问来源于stack exchange,提问作者Kibotu
相关产品推荐
相关产品推荐

