2

サーバーからファイルをダウンロードし、この操作中にローカル DB に解析して挿入しています。進行状況バーを使用して操作の進行状況を表示しています。ファイルが非常に大きいため、進行状況バーに 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

はい、UI以外のタスクを実行する場合は、doInBackground()メソッドで実行する必要があります。メインスレッドで動作するAsyncTaskのメソッドで長時間実行されるタスクを実行する場合は、ANRが提供されます。

于 2013-02-07T07:55:56.473 に答える
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 で必要な数の非同期タスクを実行することです。

ただし、ファイルが大きい場合は、 thread/queue-worker pattern/service の使用を検討する必要があります。

于 2013-02-07T07:50:03.810 に答える
0

AsyncTask を使用する前に、以下をお読みください

簡単に言うと、Activity のメソッドから AsyncTask を呼び出すことは概念的に欠陥があります。長い操作は、それを開始したアクティビティよりも長生きする可能性があるためです。このような操作は、(MVC の意味で) モデルの責任である必要があります。その場合、おそらく AsyncTask よりも深刻なものになるでしょう。

于 2013-02-07T09:32:02.673 に答える