0

AsyncTask約 100,000 の数字を調べて、その数字ごとにデータを取得する必要があります。1,000 個のパラメータが送信された場合は問題なく動作し、10,000 個のパラメータでも動作しますが、非常に遅くて遅延があります。RejectedExecutionException最初に、実行するすべての数値の配列を送信していましたが、約 60,000 の数値を超えるとExeptions.

この場合のコードは次のとおりです。

for(int i = 0; i < 70000; i++){
    numbers[i] = i;
}

new NetTask().execute(numbers);

また、この場合は AsyncTask :

public class NetTask extends AsyncTask<Integer, String, String>
    {
        @Override
        protected String doInBackground(Integer... params)
        {   
            for (Integer number : params) {
                    try {
                        // DO NETWORK STUFF
                        publishProgress(number+" Successful");
                    } catch (Exception ex) {
                        publishProgress(number+" Failed");
                    }
            }
            return "";
        }
    }

次に、このような量のパラメーターでタスクを実行する必要がある場合、たとえばすべての値をループすることにより、単一の AsyncTask 内で処理する方がよいことをどこかで読みました。以前に使用したコードは大量の AsyncTask を作成するためです。そのため、「:」で区切られた単一の文字列で数値を送信してから、AsyncTask でそれらを単一の数値に切り戻し、それらを使用してタスクを実行しようとしましたが、以前の試行と同様の結果が得られました。

この場合の AsyncTask は次のとおりです。

public class NetTask extends AsyncTask<String, String, String>
    {
        @Override
        protected String doInBackground(String... params)
        {


            for (String line : params) {

                String[] numbers = line.split(":");

                for (int i = 0; i < numbers.length; i++) {
                    int number = Integer.parseInt(numbers[i]);
                    try {
                        // DO NETWORK STUFF
                        publishProgress(number+" Successful");
                    } catch (Exception ex) {
                        publishProgress(number+" Failed");
                    }
                }
            }
            return "";
        }

私が求めているものを達成するためのより良い、実用的なアプローチを知っている人はいますか?

4

1 に答える 1

1

それでは、このような大量のタスクを実行する正しい方法は何でしょうか?

まず、Chang 氏が指摘するように、これは実際には 1 つまたはいくつかのタスクである必要があります。各タスクは、一度に多くの「数字」に関する「データを取得」する必要があります。たとえば、「データを取得する」が「Web サービスを呼び出す」を意味する場合、おそらく 100MB の帯域幅を消費する 100,000 回の Web サービス呼び出しを実行することはばかげたことではありません。または、「データの取得」が「SQLite データベースに対してクエリを実行する」ことを意味する場合は、IN100,000 の個別のデータベース クエリを実行するのではなく、1 つのデータベース操作で多数の「数値」に関する「データを取得」するために演算子を使用します。

さらに、「取得」することを選択したこの「データ」を実際に気にしていると仮定するとAsyncTask、 は適切なエンジンではない可能性があります。UI レイヤーで何が起こるかに関係なく、この作業が発生する必要がある場合は、IntentService代わりに を使用してください。これは、どのアクティビティとも独立して実行できるためです。

AsyncTaskただし、何らかの理由で 100,000のことを実行することが実際には適切であるとしましょう。varargs スタイルのメソッドに 100,000 個のパラメーターを渡そうとしたことはありません。これで問題なく動作する可能性があります。数値が連続している場合は、最初と最後の値を渡すだけで十分であり、AsyncTask非常にうまくカウントできます。または、本当に 100,000 の個別の数値を に渡す必要がありAsyncTask、Traceview が に 100,000 のパラメーターを渡すことが不適切であることを示している場合execute()は、 を作成ArrayList<Integer>してそのように渡します。

于 2012-12-22T00:13:29.843 に答える