如何在android中同时下载大量文件?

时间:2016-08-29 10:09:19

标签: android file

我想在android中同时下载一些文件,例如,有10000个文件需要下载,每个文件都有20kb的小文件,我想要3个线程同时下载文件。

也许Asynctask适合?并且可能需要一个队列来管理10000个URL?

有些评论提到了DownloadManager.class,它是否支持并发下载?因为文件太多而且文件大小很小,我认为同时执行它会更快。

1 个答案:

答案 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
        
                    }
        
                }
        
        }
        
    }