我正在制作一个基于地图的应用,用户通常会在地图上加载超过10k的多边形。唯一的问题是向地图添加多边形的唯一方法是在UI线程中,这意味着当我添加它们时,它将冻结5-10秒或者它将崩溃。
我已经准备好接受它只需要花时间加载,但是有一种方法可以在系统努力防止崩溃甚至冻结时减慢for循环吗?我想到的一种方法是在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 :(得分: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);
}
};
希望它对你有所帮助。
答案 1 :(得分:1)
将其拆分为多个任务,并分别在主线程上执行每个任务。即。
for (int i = 0; i < 20; ++i) {
runOnUiThread(new Runnable() { .. process 1/20 of your work });
}
您无需添加延迟。您也可以尝试粒度,可能最好将其从1/20增加。