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

1.4k views Asked by At

I am using android maps api v2 with the android-maps-extensions to cluster, and adding almost 1000 marker to the map. 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. 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.

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:

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. 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.

I tried these things:

  1. Add markers in the onPostExecute
  2. Create BitmapDescriptor once

How to make these add markers without block the UI thread? All the read and download I already did in background thread, but add markers needs to be executed in the UI thread! Is it correct? Is there a way to add these markers in a background thread? How do I fix or do a workaround?

P.s: Sorry because my bad english, I'm learning android and English simultaneously!! =D

Thanks

2

There are 2 answers

4
MaciejGórski On BEST ANSWER

The problem with your code seems to be calling publishProgress in a loop. Instead do that loop in onPostExecute.

3
tyczj On

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.

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. 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