2

我正在从服务器下载文件,然后解析并插入本地数据库,而此操作我正在使用进度条显示操作进度。由于文件非常大,因此解析需要 2-4 分钟,因此我在进度条上收到 ANR下载完成后进度条也没有更新,它只显示 50% 的进度。如何避免这种 ANR?我附上我的代码如下...

@Override
    protected void onPreExecute() 
    {
            flag = false;
            progressCount = 0;
            ProgressDialog progressBar = DdownoadProgressBar(context,
            progressCount);
            progressBar.show(); 

    }

    @Override
    protected Integer doInBackground(String... urls) {
        checkNetworkConnection();

        if (connectionFlag) {
            downloadFile1();
            progressCount = 1;
            publishProgress(progressCount);

            downloadFile2();
            progressCount = 2;
            publishProgress(progressCount);

            downloadFile3();
            progressCount = 3;
            publishProgress(progressCount);

            downloadFile4();
            progressCount = 4;
            publishProgress(progressCount);

            downloadFile5();
            progressCount = 5;
            publishProgress(progressCount);

            downloadFile6();
            progressCount = 6;
            publishProgress(progressCount);

            downloadflag = true;
        }
        return null;
    }


    @Override
    protected void onProgressUpdate(Integer... progress) 
    {
        Log.v(TAG, "In progressUpdate...");

        progressBar.setProgress(progressCount);

    }

    @Override
    protected void onPostExecute(Integer progress) {
        if (downloadflag) {
            try {

                Log.v(TAG, "Inside onPostExecute....");

                 parseFile1();
                 progressCount=7;
                 publishProgress(progressCount);

                 parseFile2();
                 progressCount=8;
                 publishProgress(progressCount);

                 parseFile3();
                 progressCount=9;
                 publishProgress(progressCount);

                 parseFile4();
                 progressCount=10;
                 publishProgress(progressCount);

                 parseFile5();
                 progressCount=11;
                 publishProgress(progressCount);

                 parseFile6();
                 progressCount=12;
                 publishProgress(progressCount);

                 progressBar.dismiss();
                 Toast.makeText(SynchronizeData.this,"Data is successfully downloaded from server.......", Toast.LENGTH_LONG).show();

            } catch (Exception e) {

                e.printStackTrace();
            }
        } else {

            progressBar.dismiss();

            Toast.makeText(
                    getApplicationContext(),
                    "File is not downloaded....Error in network connection...........",Toast.LENGTH_LONG).show();
            Log.v(TAG, "File is not downloaded...............");

        }
    }
4

5 回答 5

1

将解析逻辑移动到 doinBackground() ,如下面的代码。

@Override
protected void onPreExecute() 
{
        flag = false;
        progressCount = 0;
        ProgressDialog progressBar = DdownoadProgressBar(context,
        progressCount);
        progressBar.show(); 

}

@Override
protected Integer doInBackground(String... urls) {
    checkNetworkConnection();

    if (connectionFlag) {
        downloadFile1();
        progressCount = 1;
        publishProgress(progressCount);

        downloadFile2();
        progressCount = 2;
        publishProgress(progressCount);

        downloadFile3();
        progressCount = 3;
        publishProgress(progressCount);

        downloadFile4();
        progressCount = 4;
        publishProgress(progressCount);

        downloadFile5();
        progressCount = 5;
        publishProgress(progressCount);

        downloadFile6();
        progressCount = 6;
        publishProgress(progressCount);

        downloadflag = true;
    }

    if (downloadflag) {
        try {

             parseFile1();
             progressCount=7;
             publishProgress(progressCount);

             parseFile2();
             progressCount=8;
             publishProgress(progressCount);

             parseFile3();
             progressCount=9;
             publishProgress(progressCount);

             parseFile4();
             progressCount=10;
             publishProgress(progressCount);

             parseFile5();
             progressCount=11;
             publishProgress(progressCount);

             parseFile6();
             progressCount=12;
             publishProgress(progressCount);

        } catch (Exception e) {

            e.printStackTrace();
        }
    }
    return null;
}


@Override
protected void onProgressUpdate(Integer... progress) 
{
    Log.v(TAG, "In progressUpdate...");

    progressBar.setProgress(progressCount);

}

@Override
protected void onPostExecute(Integer progress) {

        try {

            Log.v(TAG, "Inside onPostExecute....");


             progressBar.dismiss();
             Toast.makeText(SynchronizeData.this,"Data is successfully downloaded from server.......", Toast.LENGTH_LONG).show();

        } catch (Exception e) {

            e.printStackTrace();
        }

}
于 2013-02-07T08:01:32.780 回答
1

将您的解析逻辑移动到 doInBackground 方法中。没有理由在后台线程上进行 Web 调用并在 UI 线程上进行解析。

于 2013-02-07T07:46:49.137 回答
1

正如 Rich 所说:在 doInBackground 中解析文件。

其他选项是在 onPostExecute 中运行尽可能多的异步任务。

但是如果文件很大,你应该考虑使用线程/队列工作者模式/服务!

于 2013-02-07T07:50:03.810 回答
1

是的,您所做的任何非 UI 任务都必须在 doInBackground() 方法中完成。如果您将在主线程中工作的 AsyncTask 方法中执行长时间运行的任务,那么它将给您 ANR。

于 2013-02-07T07:55:56.473 回答
0

在使用 AsyncTask 之前,请阅读: AsyncTask 在概念上真的存在缺陷还是我只是遗漏了什么?

简而言之:从 Activity 的方法调用 AsyncTask 在概念上是有缺陷的,因为长时间的操作可能比启动它的 Activity 寿命更长。这样的操作应该是模型的责任(在 MVC 意义上),在这种情况下,它可能会比 AsyncTask 更严重。

于 2013-02-07T09:32:02.673 回答