2017-10-22 5 views
0

マップ上に10kポリゴンをロードするマップベースのアプリケーションを作成しています。唯一の問題は、マップにポリゴンを追加する唯一の方法はUIスレッドにあることです。つまり、追加すると5〜10秒間フリーズするか、クラッシュします。重いプロセスでクラッシュするのを防ぐ

私はロードするのに時間がかかることを受け入れる準備はできていますが、システムがクラッシュや凍結を防ぐために苦労しているときにforループを遅くする方法がありますか?私が考えている方法の1つは、forループに短い遅延を置くことですが、それは安全な側にする必要があるため、ずっと長い時間を要しますので、理想的ではありません。

  protected void onPostExecute(HashMap<String, ArrayList> result){ 
      for(String key : result.keySet()){ 
       List<PolygonOptions> thisList = result.get(key); 
       for(PolygonOptions poly: thisList){ 
        Polygon thisPoly = mMap.addPolygon(poly); 
       } 
      } 
      } 
+0

あなたのコードを投稿してください。 –

+0

私は問題が「地図上に10kポリゴン以上」を読み込もうとしていると思います。ユーザーはマップ上で10Kポリゴンを一度に知覚することはできません。これは、地図上に10Kのマーカーを一度に配置しようとするのと同じことです。そのために、マーカーのクラスタリングを使用して、情報の過負荷を軽減し、パフォーマンスを向上させます。 – CommonsWare

+0

@CommonsWare私はスクリーンから離れたときにそれらを隠しとして設定する方法を実装しましたが、それらを追加してマップから削除するのはずっと難しく、表示するのではなくシステムを追加/削除する方が効果的です/隠す。 –

答えて

2

ここに私はこの問題を解決する方法についての擬似コードがあります:

private final Handler handler_render_data = new Handler(); 
private int actualItemRendering; 
private static final int HANDLER_RUN_DELAY = 1000; 



    @Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // Display the message telling the user to wait 
    // This Linear Layout includes a text and cover all teh screen 
    lyt_report_progress = (LinearLayout) findViewById (R.id.lyt_report_progress); 
    lyt_report_progress.setVisibility (View.VISIBLE); 
    lyt_report_progress.requestFocus(); 
    lyt_report_progress.setClickable (true); 

    // Your code calling your async task 

} 

// Your callback from your async task 
private void callbackHere (Data myData) { 

    this.localMyData = myData; 

    // You store your data locally and start the rendering process 
    actualItemRendering = 0; 
    handler_render_data.post (createDataFromTaskResult); 
} 


private Runnable createDataFromTaskResult = new Runnable() { 

    @Override 
    public void run() { 

     if (actualItemRendering < myData.length()) { 

      // Render your data here 

      // Continue with the next item to render 
      actualItemRendering++; 
      handler_render_data.post (createDataFromTaskResult); 

     } else { 
      // All fields were rendered 
      handler.postDelayed (hideProgressBarTask, HANDLER_RUN_DELAY); 
     } 
    } 
}; 

private Runnable hideProgressBarTask = new Runnable() { 

    @Override 
    public void run() { 

     lyt_report_progress.setVisibility (View.GONE); 

    } 
}; 

は、それはあなたのお役に立てば幸いです。

+0

これを書き留める時間をとってくれてありがとう!私はまだ少し凍結していますが、それははるかに優れています。そして、私はリストサイズでそのことを正しく理解することができます。主なものは、一度にすべてではなく、順番に発射しているということです。 –

+0

複数のスレッドが同時に実行されるため、同時に複数のスレッドを起動できますが、より多くのリソースが必要になります。 –

1

いくつかのタスクに分割し、それぞれのタスクをメインスレッドで個別に実行します。私。

for (int i = 0; i < 20; ++i) { 
    runOnUiThread(new Runnable() { .. process 1/20 of your work }); 
} 

遅延を追加する必要はありません。また、粒度を試すこともできます。1/20からそれを上げるほうがよいでしょう。

+0

完璧!まさに私が何をしたのか。ありがとう。 –

関連する問題