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:
- Add markers in the onPostExecute
- 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
The problem with your code seems to be calling publishProgress in a loop. Instead do that loop in onPostExecute.