在沉重的过程中防止崩溃

时间:2017-10-22 15:05:31

标签: java android

我正在制作一个基于地图的应用,用户通常会在地图上加载超过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);
                }
            }
          }

2 个答案:

答案 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增加。