複数のファイルを同時にダウンロードする必要があるアプリを開発しています。ファイルごとAsyncTask
に独自のファイルを作成していますが、次のファイルは前のファイルが終了した後にのみダウンロードを開始します。HttpClient
サーバー側の問題でしょうか?
複数のファイルを同時にダウンロードする必要があるアプリを開発しています。ファイルごとAsyncTask
に独自のファイルを作成していますが、次のファイルは前のファイルが終了した後にのみダウンロードを開始します。HttpClient
サーバー側の問題でしょうか?
これは、HoneycombでAsyncTask管理が変更されたためです。以前は、3つのAsyncTasksを開始した場合、これらは同時に実行されていました。HC以降、が以上にtargetSdk
設定されている12
場合、これらは1つずつキューに入れられ、実行されます(この説明を参照)。これを回避するには、AsyncTasksをそのように開始します。
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
それ以外の:
task.execute(params);
古いAndroidもターゲットにする場合は、条件付きコードが必要です。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
} else {
task.execute(params);
}
または、別のヘルパークラスでラップします。
public class Utils {
public static <P, T extends AsyncTask<P, ?, ?>> void executeAsyncTask(T task) {
executeAsyncTask(task, (P[]) null);
}
@SuppressLint("NewApi")
public static <P, T extends AsyncTask<P, ?, ?>> void executeAsyncTask(T task, P... params) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
} else {
task.execute(params);
}
}
}
使用法は次のようになります。
Utils.executeAsyncTask( new MyAsyncTask() );
最初に導入されたとき、AsyncTasksは単一のバックグラウンドスレッドでシリアルに実行されていました。DONUT以降、これはスレッドのプールに変更され、複数のタスクを並行して操作できるようになりました。HONEYCOMB以降、並列実行によって引き起こされる一般的なアプリケーションエラーを回避するために、タスクは単一スレッドで実行されます。ソース
したがって、バージョンによっては、AsyncTaskは並行して実行されません。ファイルのダウンロードなどのタスクでは、 Executorを使用してスレッドプールを使用する必要があります
または、executeOnExecutorメソッドを使用できます。
アプリケーション全体でHttpClientのインスタンスを共有し、AsyncTasksに独自のメソッドを指定しているようです。までに、リンクが古いバージョンのものであることを十分に認識していますが、ドキュメントは4.x用に更新されていないようです。