简体   繁体   English

使用Android-Maps-Extensions的Android Maps V2会非常慢地添加大量标记

[英]Android Maps V2 with Android-Maps-Extensions add lots of markers very slow

I am using android maps api v2 with the android-maps-extensions to cluster, and adding almost 1000 marker to the map. 我正在使用android maps api v2和android-maps-extensions进行聚类,并在地图上添加了近1000个标记。 In the app's first run, I download the data from the webservice using a background thread and save in the SQLite, after this add the markers to the map. 在应用程序的第一次运行中,我使用后台线程从Web服务下载数据并保存在SQLite中,之后将标记添加到地图中。 When I add these markers on the map when the map is shown the ui thread is blocked during 3 seconds, during this time is impossible to move the map and the progress bar that I use stops too. 当我在地图上显示这些标记时,ui线程在3秒内被阻止,在此期间无法移动地图,我使用的进度条也会停止。

That's the code that I use to add markers on the map: 这是我用来在地图上添加标记的代码:

private class ReadMarkersFromDB extends AsyncTask<String, UpdateEstacionamentoMap, ArrayList<UpdateEstacionamentoMap>> {

    @Override
    protected ArrayList<UpdateEstacionamentoMap> doInBackground(String... params) {

        EstacionamentoDAO estacionamentoDAO = new EstacionamentoDAO();

        SQLiteHelper sqh = new SQLiteHelper(getApplicationContext());
        SQLiteDatabase sqdb = sqh.getWritableDatabase();

        //Caso tenha informado a string para seleção, usa
        String selection = "";
        if(params[0] != null && !params[0].isEmpty())
        {
            selection = params[0];
        }

        //Pega todos os estacionamentos
        ArrayList<Estacionamento> estacionamentos = estacionamentoDAO.get(sqdb,selection);

        sqdb.close();
        sqh.close();

        //Armazena o que deve ser feito no mapa. Operações: Excluir, Incluir ou Atualizar os estacionamentos
        ArrayList<UpdateEstacionamentoMap> atualizarMapa = new ArrayList<UpdateEstacionamentoMap>();

        //Se não passou nenhuma string para seleção, logo retornou todos os registros e no mapa não tem nada, portanto somente inclui tudo no mapa
        if(selection == null || selection.isEmpty())
        {
            //Itera os estacionamentos retornados na consulta
            for(Estacionamento estacAux : estacionamentos)
            {
                //AQUI É ONDE MANDA INCLUIR O PIN NO MAPA
                publishProgress(new UpdateEstacionamentoMap(estacAux,null,0)); //0 = Incluir Pin do Estacionamento
            }
        }else //Se passou algum "selection" assume que já tem coisas no mapa e precisa apenas atualizar o conteúdo já existente no mapa
        {
            ...
        }

        return atualizarMapa;
    }

    @Override
    protected void onProgressUpdate(UpdateEstacionamentoMap... updateEstac)
    {
        if(updateEstac[0].operacao == 0) //Incluir pin no mapa 
        {
            //AQUI É ONDE INCLUI O PIN NO MAPA
            if(!updateEstac[0].estac.getDeletado()) //Inclui no mapa se o estacionamento não estiver deletado
                map.addMarker(options.data(updateEstac[0].estac).position(updateEstac[0].estac.getLocation()).title(updateEstac[0].estac.getNome()).snippet(updateEstac[0].estac.getEndereco()).icon(icon));
        }
        else
        {
        ...
        }

    }

    @Override
    protected void onPostExecute(ArrayList<UpdateEstacionamentoMap> estacionamentos) {


    }
}

I'm using addMarkersDinamically: 我正在使用addMarkersDinamically:

ClusteringSettings clusteringSettings = new ClusteringSettings().clusterOptionsProvider(new MyClusterOptionsProvider(getResources()));
clusteringSettings.addMarkersDynamically(true); //Adiciona os pins somente na região visível pelo usuário

double clusterSize = 70; //Configuração para considerar dois pontos um cluster
clusteringSettings.clusterSize(clusterSize);

map.setClustering(clusteringSettings);

The problem occur only in the first run!! 问题只发生在第一次运行!! After download the data, when the app opens I read from the SQLite and it's very fast, when the maps is shown, the markers already are on the map without any delay. 下载数据后,当应用程序打开时,我从SQLite读取并且它非常快,当显示地图时,标记已经在地图上没有任何延迟。 PERFECT!! 完善!!

I think the problem is when the markers are put on the map after the map is shown. 我认为问题是在显示地图后将标记放在地图上。 I saw that the time spend to read markers from DB and add on the map is usually 800 ms. 我看到从DB读取标记并在地图上添加的时间通常是800毫秒。

I tried these things: 我试过这些东西:

  1. Add markers in the onPostExecute 在onPostExecute中添加标记
  2. Create BitmapDescriptor once 创建一次BitmapDescriptor

How to make these add markers without block the UI thread? 如何在不阻止UI线程的情况下添加标记? All the read and download I already did in background thread, but add markers needs to be executed in the UI thread! 我已经在后台线程中进行了所有的读取和下载,但是需要在UI线程中执行添加标记! Is it correct? 这是正确的吗? Is there a way to add these markers in a background thread? 有没有办法在后台线程中添加这些标记? How do I fix or do a workaround? 我该如何修复或解决方法?

Ps: Sorry because my bad english, I'm learning android and English simultaneously!! Ps:抱歉,因为我的英语不好,我正在学习机器人和英语! =D = d

Thanks 谢谢

there is no way (Besides clustering the markers or checking if the marker is within the visible bounds of the map) to make the plot not block the UI since they have to be plotted on the UI thread. 没有办法(除了聚类标记或检查标记是否在地图的可见边界内)以使绘图不阻止UI,因为它们必须在UI线程上绘制。

chances are you dont need all 1000 markers to be displayed at once so I would look into checking if the marker is in the visible bounds of the map and only plot that marker if it is. 您可能不需要同时显示所有1000个标记,因此我会检查标记是否在地图的可见边界内,并且只绘制该标记(如果是)。 Doing this you could use a separate thread but then you will need a handler to call back to the main thread when there is a marker you need to plot 这样做你可以使用一个单独的线程,但是当你需要绘制一个标记时,你将需要一个处理程序来回调主线程

The problem with your code seems to be calling publishProgress in a loop. 您的代码的问题似乎是在循环中调用publishProgress。 Instead do that loop in onPostExecute. 而是在onPostExecute中执行该循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM