【发布时间】:2013-05-15 22:40:03
【问题描述】:
我有一个应用程序,用户可能需要在其中下载多达 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 次下载,直到该下载也失败。我感觉这是由于时间问题,Thread.sleep(10) 行似乎有点“骇人听闻”。
当然,从另一个AsyncTask 调用数百个AsyncTasks 并不是最有效的方法。如何更改此代码或实施第 3 方解决方案以适应此任务?
【问题讨论】:
-
真的需要异步下载吗?我觉得将它们排成队列并一次下载一个就可以了。
-
它没有必须,但通过异步执行此操作,我可以(最终)一次管理 2 或 3 个下载,从而提高整体速度。当然,我首先需要一个可靠的方法。
标签: java android asynchronous httprequest