使用Google地图首次推出的活动非常缓慢

我想在我的Activity中有一个SupportMapFragment。 我将这个片段直接添加到布局xml中,并将此布局设置为内容视图。 但是当Activity第一次启动的时候,需要很长时间(超过1秒)。 下一次启动是好的,需要几毫秒。

我试过了:

  • 删除任何初始化
  • 使用MapFragment而不是SupportMapFragment
  • 以编程方式添加MapFragment

但没有任何帮助。 地图显示没有任何问题或可疑的日志。

你有什么build议,是什么原因以及如何改进?

编辑:我有一个ListView,当用户点击项目,它启动与MapFragment的DetailActivity。 在点击项目之后,DetailActivity出现之前会有明显的延迟。 只有方法onCreate,我调用setContentView,运行超过1秒。 而活动在onCreate方法中,这个活动没有可见的内容。 点击和显示内容之间的这种延迟不是非常用户友好的。

谢谢

Solutions Collecting From Web of "使用Google地图首次推出的活动非常缓慢"

第一次加载需要这么长时间的原因是因为Play Services API必须以日志行forms加载:

I/Google Maps Android API﹕ Google Play services client version: 6587000 I/Google Maps Android API﹕ Google Play services package version: 6768430 

不幸的是,“包”只需要一秒左右的时间来加载和使用MapsInitializer只会让你成为“客户端”。 所以这里没有这么漂亮的工作:在主发射器的活动中初始化一个虚拟地图。

 mDummyMapInitializer.getMapAsync(new OnMapReadyCallback() { @Override public void onMapReady(GoogleMap googleMap) { Log.d(TAG, "onMapReady"); } }); 

现在当你稍后加载你的实际地图时,它不应该初始化Play服务API。 这不应该导致主要活动的任何延迟,因为asynchronous方法执行主线程。

既然你不得不在初始化的地方进行初始化,我认为在应用程序启动的时候做正确的事情是很有意义的,所以当你加载一个实际需要一个地图的活动的时候,你根本不需要等待。

注意: mDummyMapInitializer必须是MapFragmentSupportMapFragment并且必须添加到活动中,否则Play Services API将不会被加载。 getMapAsync方法本身也必须从主线程调用。

好,所以我只是有同样的问题,并认为,在查看这个问题后,没有“好”的解决scheme。

我目前的做法是延迟添加片段,让Activity有机会在添加地图之前渲染所有内容。

现在,我将地图作为子页面embedded,所以我的代码如下所示:

  // inside onCreateView new Handler().postDelayed(new Runnable() { @Override public void run() { if (isAdded()) { FragmentManager fm = getChildFragmentManager(); GoogleMapFragment mapFragment = GoogleMapFragment .newInstance(); fm.beginTransaction() .replace(R.id.mapContainer, mapFragment).commit(); } } }, 1000); 

如果直接添加到活动,它可能看起来像这样:

  // inside onCreate new Handler().postDelayed(new Runnable() { @Override public void run() { if (!isFinishing()) { FragmentManager fm = getFragmentManager(); GoogleMapFragment mapFragment = GoogleMapFragment .newInstance(); fm.beginTransaction() .replace(R.id.mapContainer, mapFragment).commit(); } } }, 1000); 

不过,需要在Runnable里面进行检查,以确保我们不会将映射添加到某个不存在的Activity或Fragment中。

我不喜欢这样的硬编码延迟,如果我想出更好的东西,将会返回。 1秒,应该是很多,但可能会更less。

我也一直在处理这个问题,并通过以下方面取得了很大的进展:

1)拔下USB电缆(或断开您的debugging会话)并再次尝试。 debugging会话处于活动状态时,应用中的Google地图速度慢得多。 断开debugging器,它变得快得多…它当然不是最快的,但至less可以接受。

2)不要调用setMapType(),除非你已经调用了getMapType()并确认它不同于你想要设置的。 多次调用相同的地图types仍然会导致它每次重置,这可能需要一段时间。

3)以编程方式添加地图片段,类似于@cYrixmorten发布的地图片段,但是我从onResume()的末尾开始的后台线程执行,然后等待50ms,然后在UI线程上运行它。 这使它不会立即触及UI线程,从而给Activity时间加载和显示; 你至less应该在屏幕上,而地图可能会窒息一切。

这里的想法是,你只想为每个活动创build一个新的MapFragment实例,而不是每次旋转屏幕方向。 我所做的就是调用“getFragmentManager()。findFragmentById(R.id.mapContainer)”,它会给我上一次的地图片段句柄,或者如果这是第一次,则会返回null(在这种情况下,我将创build地图片段并执行FragmentManager.replace())。

我通过在我的Application.onCreate()中使用MapsInitializer来解决它:

 MapsInitializer.initialize(this); 

好的结果和更干净(而不是哈克)解决scheme!

我有一个“主要”活动 – 和一个mapView的活动。 当那个activity-with-mapView第一次启动的时候,它真的很慢。

clocksmith的文章给了我一个想法,开始从主要活动在一个单独的线程初始化。 它真的解决了这个问题。

这是我的代码从“主”活动:

 public void onCreate(Bundle savedInstanceState) { ... Runnable initMap = () -> { BaseApplication.d("Start init mapView"); MapView mapView = new MapView(MainActivity.this); mapView.onCreate(null); BaseApplication.d("... done"); }; new Thread(initMap).start(); } 

mapView永远不会被使用 – 这只是初始化的目的。

这里是一个堆栈跟踪 – 仅供参考:

 12-09 19:31:54.442 17172-17341/my.app D/XXX: Start init mapView 12-09 19:31:54.525 17172-17341/my.app I/zzy: Making Creator dynamically 12-09 19:31:55.007 17172-17341/my.app D/ChimeraCfgMgr: Reading stored module config 12-09 19:31:55.153 17172-17341/my.app D/ChimeraCfgMgr: Loading module com.google.android.gms.maps from APK /data/user/0/com.google.android.gms/app_chimera/chimera-module-root/module-71c764a6f3cb92bdc5525a965b589e7c5ed304f3/MapsModule.apk 12-09 19:31:55.154 17172-17341/my.app D/ChimeraModuleLdr: Loading module APK /data/user/0/com.google.android.gms/app_chimera/chimera-module-root/module-71c764a6f3cb92bdc5525a965b589e7c5ed304f3/MapsModule.apk 12-09 19:31:55.262 17172-17341/my.app D/ChimeraFileApk: Primary ABI of requesting process is armeabi-v7a 12-09 19:31:55.271 17172-17341/my.app D/ChimeraFileApk: Classloading successful. Optimized code found. 12-09 19:31:55.316 17172-17341/my.app W/System: ClassLoader referenced unknown path: /data/user/0/com.google.android.gms/app_chimera/chimera-module-root/module-71c764a6f3cb92bdc5525a965b589e7c5ed304f3/native-libs/armeabi-v7a 12-09 19:31:55.317 17172-17341/my.app W/System: ClassLoader referenced unknown path: /data/user/0/com.google.android.gms/app_chimera/chimera-module-root/module-71c764a6f3cb92bdc5525a965b589e7c5ed304f3/native-libs/armeabi 12-09 19:31:55.618 17172-17341/my.app I/Google Maps Android API: Google Play services client version: 7571000 12-09 19:31:55.630 17172-17341/my.app I/Google Maps Android API: Google Play services package version: 8489438 12-09 19:31:55.969 17172-17341/my.app I/e: Token loaded from file. Expires in: 423267993 ms. 12-09 19:31:55.969 17172-17341/my.app I/e: Scheduling next attempt in 422967 seconds. 12-09 19:31:56.338 17172-17341/my.app D/XXX: ... done 

正如我们所看到的,真的需要很多时间

对我来说,这是比1秒慢,因为我正在使用:

 mapFragment.getMap(); 

然后我改为:

  mapFragment.getMapAsync(new OnMapReadyCallback() { @Override public void onMapReady(GoogleMap googleMap) { map = googleMap; } }); 

使用getMapAsync()将不会阻止用户界面,所以您的活动将在地图之前加载。 它仍然很慢,但对我的目的,只是显示一个加载消息是好的。

类似于这里的其他解决scheme,但使用RxJava + RxAndroid。

只需从启动器活动onCreate调用此片段即可。

 Observable.fromCallable(new Callable<Void>() { @Override public Void call() { MapView mapView = new MapView(LaunchActivity.this); // Replace LaunchActivity with appropriate activity's name mapView.onCreate(null); return null; } }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe( new Action1<Void>() { @Override public void call(Void ignorable) { Log.i("Google Maps", "Initialised Google Maps."); } }, new Action1<Throwable>() { @Override public void call(Throwable ignorable) { Log.w("Google Maps", "[EXPECTED] Initialized Google Maps but got: " + ignorable.getMessage()); } });