I have been writing a file download module, when user select some files and click download button, it will create as many AsyncTasks as the files. All these files were added to an array. Then I traverse the array, create an AsyncTask for the file, call execute
method of each AsyncTask instance.
I tested this module by downloading 20 photos, 1 MB each, turned out it can successfully download these files and being stable. But problem comes when I add thousands of files, for example 2000 photos, to download.
When user click to download those 2000 photos, it will create 2000 AsyncTasks and call execute
method of each immediately. That`s not the best practice, or even cause OOM, I think. Because it starts 2000 threads at the same time, though only the top 5 AsyncTask instances will invoke their doInbackground
method on Kitkat according to official document, 2000 threads were created and allocated resources already (right?) which may leads up to OOM.
For a better performance, I plan to manage these AsyncTasks in a queue, only poll top five instances and execute them, anyone is done executing, it sends a notification and poll a substitute one out until all remaining AsyncTasks have been executed. I wonder if it is right to think like this. Thanks in advance!
method for add download task
/**
* 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();
}
call addDownloadTask in a loop
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));
}
}
}