ユーザーが最大 760 個のファイル (合計で約 350MB) をダウンロードする必要があるアプリがあります。これらのファイルを圧縮することはできません。ルーズ ファイルとしてダウンロードする必要があります。
現在、Android Asynchronous Http Clientを使用して個々のファイルをダウンロードAsyncTask
し、プロセス全体を実行しています。
DownloadThread
バックグラウンドで何百ものファイルのダウンロードを処理するオブジェクトの例を次に示します。
public class DownloadThread extends AsyncTask<String,String,String> {
ArrayList<String> list;
AsyncHttpClient client;
String[] allowedContentTypes = new String[] { "audio/mpeg" };
BufferedOutputStream bos;
FileOutputStream fos;
@Override
protected String doInBackground(String... params) {
DownloadTask task;
for (String file : list) {
//the "list" variable has already been populated with hundreds of strings
task = new DownloadTask(file);
task.execute("");
while (!task.isdone)
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
class DownloadTask extends AsyncTask<String, String, String> {
String character, filename;
boolean isdone = false;
public DownloadTask(String file) {
//file = something like "Whale/sadwhale.mp3"
character = file.split("/")[0];
filename = file.split("/")[1];
}
@Override
protected void onPreExecute() {
}
@Override
protected void onPostExecute(String result) {
if (!result.equals("Error")) {
//Do something on success
}
isdone = true;
}
@Override
protected String doInBackground(String... str) {
client = new AsyncHttpClient();
client.get("http://some-site.com/sounds/" + character + "/"
+ filename, new BinaryHttpResponseHandler(
allowedContentTypes) {
@Override
public void onSuccess(byte[] fileData) {
try {
// Make file/folder and create stream
File folder = new File(Environment
.getExternalStorageDirectory()
+ CharSelect.directory + character);
folder.mkdirs();
File dest = new File(folder, filename);
fos = new FileOutputStream(dest);
bos = new BufferedOutputStream(fos);
// Transfer data to file
bos.write(fileData);
bos.flush();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
});
return "Success";
}
}
}
DownloadThread
バックグラウンドで実行され、何百もの独自のAsyncTasks
. タスクのダウンロードが完了するまで待機し、for
ダウンロードごとにループを続行します。
これはうまくいきます。一部のダウンロードが正しく終了しないか、まったく開始されないように見えます。760 回のダウンロードのリストのうち、平均 100 回のダウンロードが正常に完了したため、プロセスを再起動して、さらに 100 回のダウンロードが失敗するまで、さらに 100 回のダウンロードをダウンロードする必要があります。Thread.sleep(10)
行が少し「ハッキー」に見えるので、これはタイミングの問題によるものだと感じています。
確かに、何百AsyncTasks
もの別のものを呼び出すAsyncTask
ことは、これを行うための最も効率的な方法ではありません。このタスクに適合するように、このコードを変更したり、サードパーティのソリューションを実装したりするにはどうすればよいですか?