android加载多个标记阻止我的UI

android加载多个标记阻止我的UI,android,google-maps-markers,Android,Google Maps Markers,我在markerarray列表中有大约11000个标记,当我尝试在map中加载时,它会阻塞我的UI,甚至当我使用Thread和RunOnUi Thread时,还有其他更好的方法吗 Thread t = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < list.size(); i

我在markerarray列表中有大约11000个标记,当我尝试在map中加载时,它会阻塞我的UI,甚至当我使用Thread和RunOnUi Thread时,还有其他更好的方法吗

 Thread t = new Thread(new Runnable() {

                @Override
                public void run() {
                    for (int i = 0; i < list.size(); i++) {

                        markerOptionList.add(new MarkerOptions().position(
                                new LatLng(Double.parseDouble(list.get(i)
                                        .getLatitude()), Double
                                        .parseDouble(list.get(i)
                                                .getLangtitude()))).title(
                                list.get(i).getName() + "~"
                                        + list.get(i).getCity() + "~"
                                        + list.get(i).getSector() + "~"
                                        + String.valueOf(false)));
                    }

                    getActivity().runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            addMarker();
                        }
                    });

                }
            });
            t.start();
Thread t=新线程(new Runnable(){
@凌驾
公开募捐{
对于(int i=0;i
添加标记是我在地图中添加标记的方法

请建议更好的实施方法
提前感谢

加载11000个制造商对设备来说是一项非常繁重的工作。即使您可以将它们全部添加到地图中,当您缩小时,也可能会面临相同的问题。
关于各种先进的标记管理技术,有很多不同的观点。使用其中一个标记仅显示必要的标记,而不是全部标记

对于您提到的标记数量(11000),使用标记聚类是非常明智的。您可以通过以下网站了解更多信息:

如果您仍然想在没有标记集群的情况下实现这一点,那么有一个简单的技巧可以改善用户体验

当添加一个标记修改UI时,它必须在主UI线程中完成。一次添加太多标记会阻塞主线程,因此应用程序在忙于添加标记时不会响应任何用户操作。最终用户可能会觉得应用程序已挂起或停止,甚至可能导致

诀窍是逐渐添加标记,为主线程处理其他操作留下一些中断,以便应用程序在整个时间内保持响应

我建议这样做:

public class DrawMarkersTask extends AsyncTask<Void, MarkerOptions, Void> {
    protected void onPreExecute() {
        // this method executes in UI thread
        googleMap.clear(); // you can clear map here for example
    }

    @Override
    protected Void doInBackground(Void... params) {
        // this method executes in separate background thread
        // you CANT modify UI here
        for (int i = 0; i < list.size(); i++) {
            // prepare your marker here
            MarkerOptions markerOptions = new MarkerOptions().position(
                            new LatLng(Double.parseDouble(list.get(i)
                                    .getLatitude()), Double
                                    .parseDouble(list.get(i)
                                            .getLongtitude()))).title(
                            list.get(i).getName() + "~"
                                    + list.get(i).getCity() + "~"
                                    + list.get(i).getSector() + "~"
                                    + String.valueOf(false)));

            publishProgress(markerOptions); // pass it for the main UI thread for displaying
            try {
                Thread.sleep(50); // sleep for 50 ms so that main UI thread can handle user actions in the meantime
            } catch (InterruptedException e) {
                // NOP (no operation)
            }
        }
        return null;
    }

    protected void onProgressUpdate(MarkerOptions... markerOptions) {
        // this executes in main ui thread so you can add prepared marker to your map
        googleMap.addMarker(markerOptions[0]);
    }

    protected void onPostExecute(Void result) {
        // this also executes in main ui thread
    }
}

注意:这只是一个技巧。它和减少或优化这个问题的复杂性无关,它只是通过及时扩展操作来向用户隐藏它。然而,这种方法有时也是可以接受的折衷办法。

您不应该一次添加所有标记。而是按需添加。可以通过使用缩放级别和地图的可见部分来确定在何时加载哪些标记来完成此操作。因此,在较低的缩放级别,您可以按区域或类似对象对标记进行分组,并且只显示该区域的一个标记,并且随着缩放的增加,增加该特定区域的标记量。我认为Android中的AsyncTask可以帮助您在for loop外部创建标记选项对象。MarkerOptions MarkerOptions=新MarkerOptions();带有Progressdialog的异步任务帮助me@Madhu它不需要您删除任何标记。您可以在不同的缩放级别上显示它们。即使你可以一次展示它们,它们仍然会相互重叠。这种方法对我来说非常有效。我设置了
Thread.sleep(1)
,在加载标记时仍然允许大量用户交互。谢谢你的全面回答。
DrawMarkersTask drawMarkersTask = new DrawMarkersTask();
drawMarkersTask.execute();