4

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 Answers2

0

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

tyczj
  • 71,600
  • 54
  • 194
  • 296
  • Thanks for the response!! The cluster framework already plot on the map only in the visible area!! I think I don't need to control this. But the idea to use a background thread to process only the pins in visible region is interesting. I will try this if i cannot use the cluster framework well. Thanks – Leandro Boni Jan 07 '14 at 21:58
  • @LeandroBoni Yes. Extensions is adding only markets in the visible area when you use addMarkersDynamically. – MaciejGórski Jan 07 '14 at 22:14
  • Thanks for the confirmation!! The cluster do all perfect after add markers. The problem is add markers when the map is shown. I did a little test now, adding only 50 markers to the map the block persists! – Leandro Boni Jan 07 '14 at 22:55
0

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

MaciejGórski
  • 22,187
  • 7
  • 70
  • 94
  • Thaks for response. I tried using the onPostExecute but the result was the same. And using with publishProgress when the map is not shown is very fast!! Any other idea? – Leandro Boni Jan 07 '14 at 22:53
  • @LeandroBoni Can you say exactly what takes what amount of time? Like splitting `time spend to read markers from DB **and** add on the map is usually 800 ms` into two times and how does it relate to `ui thread is blocked during 3 seconds`. – MaciejGórski Jan 08 '14 at 11:45
  • i resolved the problem!! It's a basic error of mine!! I did what you said and I saw the problem was in the saving data in the SQLite. I'm using Volley framework to do the request, and I thought the callback was executed in another thread too, so I was saving data to DB. Thanks very much dude!! You help me a lot.. how can I close this answer? I'm new in StackOverflow!! – Leandro Boni Jan 08 '14 at 19:19
  • @LeandroBoni On the left of an answer there should be unfilled tick mark, which you click to accept the answer as correct. Also you may want to click triangle pointing up any time (not only on your questions) to indicate the answer or question was useful to you. – MaciejGórski Jan 09 '14 at 08:46