Android 是什么让我的地图片段加载缓慢?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26265526/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:10:55  来源:igfitidea点击:

what makes my map fragment loading slow?

androidandroid-maps-v2android-maps

提问by Haifeng Zhang

Performance Enhancement:

性能增强:

Previously I saved ALLimages in drawablefolder, this might be the reason why the map first loads slow, when draw the markers on screen, the image may not fit the screen size. NowI saved images in drawable-mdpi, drawable-hdpiand so on, the app works smoother than before. Hope it helps

以前我将所有图像保存在drawable文件夹中,这可能是地图首次加载缓慢的原因,在屏幕上绘制标记时,图像可能不适合屏幕尺寸。现在我将图像保存在drawable-mdpidrawable-hdpi等等,应用程序比以前更流畅。希望能帮助到你

Original Question:

原问题:

I created a map in a fragment, the source code can be found below.

我在一个片段中创建了一个地图,源代码可以在下面找到。

The map fragment is sluggish when the first timeit loads. If I go any other fragment and click the map fragment again, it loads fast and no slug anymore.

地图片段在第一次加载时缓慢。如果我转到任何其他片段并再次单击地图片段,它会加载得很快并且不再有段塞。

Can anyone tell me what is going on here? Thanks!

谁能告诉我这里发生了什么?谢谢!

fragment_map.xml, id is map

fragment_map.xml,id 是 map

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:map="http://schemas.android.com/apk/res-auto"
          android:id="@+id/map"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:name="com.google.android.gms.maps.SupportMapFragment"/>

MyMapFragment.java (contains onCreateViewand setUpMapIfNeeded)

MyMapFragment.java(包含onCreateViewsetUpMapIfNeeded

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    try {
        rootView = inflater.inflate(R.layout.fragment_map, container, false);
    } catch (InflateException e) {
    /* map is already there, just return view as it is */
        Log.e(TAG, "inflateException");
    }

     setUpMapIfNeeded();

    return rootView;
}


public void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the fragment_map.
        if (myMap == null) {
            // Try to obtain the fragment_map from the SupportMapFragment.
            myMap = ((SupportMapFragment) MainActivity.fragmentManager.findFragmentById(R.id.map)).getMap();
            // Check if we were successful in obtaining the fragment_map.
            if (myMap != null) {
                setUpMap();
            }
        }
    }

回答by Xyaren

I'm using a very hackish but effective way in my application, but it works good. My mapFragment is not displayed right after the app launches! Otherwise this would not make sense.

我在我的应用程序中使用了一种非常黑客但有效的方法,但效果很好。应用程序启动后,我的 mapFragment 未立即显示!否则这将没有意义。

Put this in your launcher activity's onCreate:

把它放在你的启动器活动的onCreate 中

    // Fixing Later Map loading Delay
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                MapView mv = new MapView(getApplicationContext());
                mv.onCreate(null);
                mv.onPause();
                mv.onDestroy();
            }catch (Exception ignored){

            }
        }
    }).start();

This will create a mapview in an background thread (far away from the ui) and with it, initializes all the google play services and map data.

这将在后台线程(远离用户界面)中创建一个地图视图,并用它初始化所有 google play 服务和地图数据。

The loaded data is about 5MB extra.

加载的数据大约额外 5MB。

If someone has some ideas for improvements feel free to comment please !

如果有人有一些改进的想法,请随时发表评论!



Java 8 Version:

Java 8 版本:

// Fixing Later Map loading Delay
new Thread(() -> {
    try {
        MapView mv = new MapView(getApplicationContext());
        mv.onCreate(null);
        mv.onPause();
        mv.onDestroy();
    }catch (Exception ignored){}
}).start();

回答by Conti

Just to add to @Xyaren's answer, I needed it to work for SupportFragment which seemed to require some extra steps. Have your activity implement OnMapReadyCallback.

只是为了添加到@Xyaren 的答案中,我需要它为 SupportFragment 工作,这似乎需要一些额外的步骤。让您的活动实施 OnMapReadyCallback。

In your onCreate:

在您的 onCreate 中:

 new Thread(() -> {
        try {
            SupportMapFragment mf = SupportMapFragment.newInstance();
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.dummy_map_view, mf)
                    .commit();
            runOnUiThread(() -> mf.getMapAsync(SplashActivity.this));
        }catch (Exception ignored){
            Timber.w("Dummy map load exception: %s", ignored);
        }
    }).start();

You'll have to implement this:

你必须实现这一点:

@Override
 public void onMapReady(GoogleMap googleMap) {
    // Do nothing because we only want to pre-load map.
    Timber.d("Map loaded: %s", googleMap);
}

and in your activity layout:

并在您的活动布局中:

<FrameLayout
    android:id="@+id/dummy_map_view"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:visibility="gone"/>

It needs to go through all the steps including the transaction for Google Play Services to download the map data.

它需要经过所有步骤,包括 Google Play 服务下载地图数据的交易。

回答by Wookie

I had been running into this problem a lot too... Turns out the biggest culprit was having a debugging session attached to my app's process. The maps stuff in my app ran much faster and more smoothly when I disconnected the debugger, or just unplugged the USB cable.

我也经常遇到这个问题......原来最大的罪魁祸首是将调试会话附加到我的应用程序进程中。当我断开调试器的连接或拔掉 USB 电缆时,我的应用程序中的地图内容运行得更快、更流畅。

Check out my related post here: First launch of Activity with Google Maps is very slow

在此处查看我的相关帖子:首次启动 Activity with Google Maps 非常慢

回答by cybersam

[EDITED]

[编辑]

The getMap()and setUpMap()methods are probably very slow. Their processing should be done in an AsyncTaskso that onCreateView()can return quickly every time.

getMap()setUpMap()方法可能很慢。它们的处理应该以一种方式完成,AsyncTask以便onCreateView()每次都能快速返回。

More info: onCreateView()is called on the UI thread, so any slow processing that it does will freeze the UI. Your AsyncTaskshould do all the slow processing in its doInBackground()method, and then update the UI in its onPostExecute()method. See the AsyncTask JavaDocfor more details.

更多信息:onCreateView()在 UI 线程上调用,因此它所做的任何缓慢处理都会冻结 UI。您AsyncTask应该在其doInBackground()方法中完成所有缓慢的处理,然后在其onPostExecute()方法中更新 UI 。有关更多详细信息,请参阅AsyncTask JavaDoc

回答by Kelo Adler

You could try this

你可以试试这个

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mapActivity);
    getSreenDimanstions();
    fragment = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));

    map = fragment.getMap();    

}

}

This class extended Activity

此类扩展活动