我一直在写一个文件下载模块,当用户选择一些文件并单击下载按钮时,它会创建与文件一样多的 AsyncTasks。所有这些文件都被添加到一个数组中。然后我遍历数组,为文件创建一个 AsyncTask,调用每个 AsyncTask 实例的 execute
方法。
我通过下载 20 张照片,每张 1 MB 来测试这个模块,结果证明它可以成功下载这些文件并且稳定。但是当我添加数千个文件(例如 2000 张照片)进行下载时,问题就来了。
当用户点击下载这 2000 张照片时,它会创建 2000 个 AsyncTasks 并立即调用每个的 execute
方法。那不是最佳实践,甚至会导致 OOM,我认为。因为它同时启动了 2000 个线程,虽然根据官方文档只有前 5 个 AsyncTask 实例会调用它们在 Kitkat 上的 doInbackground
方法,但是已经创建了 2000 个线程并分配了资源(对吧?)这可能导致 OOM。
为了更好的性能,我计划在一个队列中管理这些 AsyncTasks,只轮询前五个实例并执行它们,任何人执行完毕,它会发送一个通知并轮询一个替代实例,直到所有剩余的 AsyncTasks 都已执行。我不知道这样想是否正确。提前致谢!
添加下载任务的方法
/**
* Add a new download task
*/
public int addDownloadTask(Account account,
String repoName,
String repoID,
String path) {
// omit lines...
DownloadTask task = new DownloadTask(account, repoName, repoID, path);
// execute download task serially
task.execute();
return task.getTaskID();
}
循环调用addDownloadTask
for (SeafDirent seafDirent : dirents) {
if (!seafDirent.isDir()) {
File localCachedFile = dataManager.getLocalCachedFile(repoName, repoID, seafDirent.name), seafDirent.id);
if (localCachedFile == null) {
txService.addDownloadTask(account, repoName, repoID, Utils.pathJoin(filePath, seafDirent.name));
}
}
}
最佳答案
您应该根据需要创建自己的Queue
及其Executor
来管理Threads
。
请看example of ThreadPool creation to manage multiple threads , ThreadPool , ThreadPool Executor
关于java - 如何在大量 AsyncTasks 运行时提高性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27222519/