我想在android中同时下载一些文件,例如,有10000个文件需要下载,每个文件都有20kb的小文件,我想要3个线程同时下载文件。
也许Asynctask适合?并且可能需要一个队列来管理10000个URL?
有些评论提到了DownloadManager.class,它是否支持并发下载?因为文件太多而且文件大小很小,我认为同时执行它会更快。
答案 0 :(得分:0)
我认为AsyncTask适合这个。 您可以创建两个队列,例如runningTasks和pendingTasks。
当您尝试下载任务时,请将其放在runningTasks列表中,并将其他任务放在pendingTasks列表中。使用AsyncTask处理程序执行在正在运行的任务列表中添加的任务。 每当任务完成时添加一个监听器。从pendingTasks中删除任务并将其添加到pendingTasks列表中。 请参阅下面的逻辑: -
public class Downloader
{
AsyncTaskScheduler scheduler;
public Downloader()
{
scheduler = new AsyncTaskScheduler();
}
public void startDownload()
{
long ts = System.currentTimeMillis();
YourAsyncTask handler = new YourAsyncTask();
scheduler.schedule(handler, ts);
}
}
public class YourAsyncTask extends AsyncTask<Void, Void, Bitmap>
{
AsyncTaskScheduler listener;
String Uri;
public YourAsyncTask(AsyncTaskScheduler listener, uri)
{
this.Uri = uri;
this.listener = listener;
}
@Override
protected Bitmap doInBackground(Void... params)
{
try {
//Do Http Download here from The URI
// return the Bitmap downloaded ;
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap)
{
this.listener.DownloadCompleted(this);
}
}
public class TaskInfo
{
AsyncTask< Void , Void, Bitmap> async;
long timeStamp;
public TaskInfo(){}
public TaskInfo(AsyncTask< Void , Void, Bitmap> async, long timeStamp)
{
this.async = async;
this.timeStamp = timeStamp;
}
public AsyncTask<Void, Void, Bitmap> getHandler()
{
return this.async;
}
public long getTimeStamp()
{
return this.timeStamp;
}
}
public interface DownloaderCompleted
{
void DownloadCompleted(AsyncTask<Void, Void, Bitmap> task);
}
public class AsyncTaskScheduler implements DownloaderCompleted
{
private static final int RUNNING_TASK_LIST_SIZE = 3;
public ArrayList<TaskInfo> runningTasks;
public LinkedList<TaskInfo> pendingTasks;
public AsyncTaskScheduler()
{
runningTasks = new ArrayList<TaskInfo>();
pendingTasks = new LinkedList<TaskInfo>();
}
public void schedule(AsyncTask<Void, Void, Bitmap> handler, long timeStamp)
{
//Running Task list is not Full add some task to it
TaskInfo taskInfo = new TaskInfo(handler,timeStamp);
if (!isRunningtaskListFull())
{
runningTasks.add(taskInfo);
//Check if the task added to the running list , is there in the pending list also , then remove it.
for(int i = 0; i< pendingTasks.size();i++)
{
if (pendingTasks.get(i).getVideoId().equals(videoId))
{
pendingTasks.remove(i);
break;
}
}
taskInfo.getHandler().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else
{
//Check if the task is in the pending list , if Yes then No Need to Add it.
boolean found = false;
for(int i = 0; i< pendingTasks.size();i++)
{
if (pendingTasks.get(i).getVideoId().equals(videoId))
{
found = true;
break;
}
}
if (found == false)
{
pendingTasks.addFirst(taskInfo);
}
}
}
public boolean isRunningtaskListFull()
{
if (runningTasks.size() == RUNNING_TASK_LIST_SIZE)
return true;
else
return false;
}
@Override
public void DownloadCompleted(AsyncTask<Void, Void, Bitmap> handler)
{
//check the task in the running list and remove .
boolean found = false;
for (int i = 0; i < runningTasks.size(); i++)
{
if (runningTasks.get(i).getHandler().equals(handler))
{
runningTasks.remove(i);
found = true;
break;
}
}
if (found == true )
{
if (pendingTasks.size() > 0)
{
TaskInfo taskInfo = pendingTasks.removeFirst();
schedule(taskInfo.getHandler(), taskInfo.getTimeStamp());
} else
{
//All Tasks Downloaded
}
}
}
}