4

android-maps-extensions を含む android maps api v2 をクラスターに使用し、ほぼ 1000 のマーカーをマップに追加しています。アプリの最初の実行では、バックグラウンド スレッドを使用して Web サービスからデータをダウンロードし、SQLite に保存します。その後、マーカーをマップに追加します。マップが表示されているときにこれらのマーカーをマップに追加すると、UI スレッドが 3 秒間ブロックされます。この間、マップを移動することはできず、使用しているプログレス バーも停止します。

これは、マップにマーカーを追加するために使用するコードです。

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) {


    }
}

私は 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);

問題は最初の実行でのみ発生します!! データをダウンロードした後、アプリが開いたときに SQLite から読み取ると、非常に高速です。マップが表示されると、マーカーは遅延なくマップ上に既に表示されています。完全!!

問題は、マップが表示された後にマーカーがマップに配置されるときだと思います。DB からマーカーを読み取り、マップに追加するのにかかる時間は通常 800 ミリ秒であることがわかりました。

私はこれらのことを試しました:

  1. onPostExecute にマーカーを追加する
  2. BitmapDescriptor を 1 回作成する

UIスレッドをブロックせずにこれらにマーカーを追加するにはどうすればよいですか? 読み取りとダウンロードはすべてバックグラウンド スレッドで行いましたが、マーカーの追加は UI スレッドで実行する必要があります。それが正しいか?これらのマーカーをバックグラウンド スレッドに追加する方法はありますか? 修正または回避策を実行するにはどうすればよいですか?

Ps: 私の英語が下手でごめんなさい、私はアンドロイドと英語を同時に学んでいます!! =D

ありがとう

4

2 に答える 2

0

コードの問題は、publishProgress をループで呼び出しているようです。代わりに onPostExecute でそのループを実行します。

于 2014-01-07T22:20:30.750 に答える