首次使用Google地图发布活动非常缓慢

non*_*hex 38 android google-maps

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

我试过了:

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

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

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

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

谢谢

clo*_*ith 20

第一次加载需要这么长时间的原因是因为Play服务API必须加载,如日志行中所示:

I/Google Maps Android API? Google Play services client version: 6587000
I/Google Maps Android API? Google Play services package version: 6768430
Run Code Online (Sandbox Code Playgroud)

不幸的是,"软件包"只需要一秒钟就可以加载并使用MapsInitializer只能获得"客户端".所以这里有一个不太好用的工作:在主启动器活动中初始化一个虚拟地图.

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

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

既然你必须在任何地方进行初始化,我认为在应用程序启动时正确执行它是有意义的,这样当你加载一个实际需要地图的活动时,你根本不必等待.

注意:mDummyMapInitializer必须是MapFragmentSupportMapFragment必须添加到活动中,否则将不会加载Play服务API.该getMapAsync方法本身也必须从主线程调用.

  • 我希望有一种方法可以在Application.java中初始化这些服务,而不必在活动中加载地图...... (6认同)

cYr*_*ten 17

好的,所以我遇到了同样的问题,并在查看这个问题后认为没有"好的"解决方案.

我目前的黑客是延迟添加片段,让Activity在添加地图之前有机会渲染其他所有内容.

现在,我将地图嵌入为子片段,因此我的代码如下所示:

    // 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);
Run Code Online (Sandbox Code Playgroud)

如果直接添加到Activity,它可能如下所示:

    // 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);
Run Code Online (Sandbox Code Playgroud)

然而,需要在Runnable内部进行检查,以确保我们不会尝试将地图添加到某些不存在的Activity或Fragment.

我不喜欢像这样的硬编码延迟,所以如果我想出更好的东西,我会回来.1秒应该是充足的,甚至可能更少.


小智 13

我在Application.onCreate()中使用MapsInitializer解决了这个问题:

MapsInitializer.initialize(this);
Run Code Online (Sandbox Code Playgroud)

良好的结果和更清洁(而不是hacky)的解决方案!


Woo*_*kie 10

我也一直在与这个问题作斗争,并通过以下方式找到了相当大的改进:

1)拔下USB电缆(或以其他方式断开调试会话)并再次尝试.调试会话处于活动状态时,应用程序中的Google地图慢得多.断开调试器的连接速度会快得多......它仍然不是最快的,但至少可以接受.

2)除非你已经调用了getMapType()并且确认它与你想要设置的不同,否则不要调用setMapType().对同一Map类型的多次调用仍会导致每次重置,这可能需要一些时间.

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

这里的问题是你想为每个Activity创建一个新的MapFragment实例,而不是每次旋转屏幕方向.我所做的是调用"getFragmentManager().findFragmentById(R.id.mapContainer)",这将给我上次的地图片段句柄,如果这是第一次给我一个null(在这种情况下我会创建)地图片段并执行FragmentManager.replace()).