【问题标题】:How to download multiple files simultaneously in Android如何在Android中同时下载多个文件
【发布时间】:2017-02-10 06:56:47
【问题描述】:

我有一个活动,它有两个列表视图。第一个列表视图有音乐。第二个列表视图显示下载项目,每个下载项目显示下载百分比的进度条。 如果用户单击音乐项目,我将下载项目添加到第二个列表视图并使用 AsyncTask 开始下载文件。用户可以点击多个音乐,这意味着同时下载多个文件。 我可以使用 AsyncTask 下载文件。但我想下载服务中的文件,因为即使应用程序关闭,下载也必须继续。

我不知道如何使用服务同时下载多个文件。我应该遵循哪些步骤?有这方面的教程吗?

【问题讨论】:

  • 不是答案,而是需要思考的问题。如果这是您的服务器,您可能希望避免同时过度下载大量文件。

标签: android service download


【解决方案1】:

我在我的一个生产应用程序中实现了相同的功能:

  1. 创建一个表格来添加您要下载的项目。排序应基于添加项目以供下载的时间。将此视为队列。还添加一列以检查文件是否已下载。如果已下载,则将其从队列中删除。
  2. 创建一个IntentService,即使应用程序关闭,它也将负责在后台下载数据。这个Service 应该一直运行,直到表队列不为空。只有在添加新项目或网络连接状态从死变为活时才应启动它。在这个Service 中,您应该检查队列是否为空。如果为空,则从表中提取 N 行以添加到队列中(ExecutorService)以供下载。要检查网络状态的变化,请创建 BroadcastReceiver‎LocalBroadcastManager
  3. 现在您可以在 DownloadIntentService 中编写代码。尝试根据您的需要进行修改:

    private static int NUMBER_OF_CORES =
        Runtime.getRuntime().availableProcessors() * 2;
    private final ExecutorService executorService;
    private final ExecutorCompletionService<DownloadModel> executorCompletionService;
    
    public DownloadIntentService() {
    super("DownloadIntentService");
    executorService = Executors.newFixedThreadPool(NUMBER_OF_CORES);
    executorCompletionService = new ExecutorCompletionService<>(executorService);
    }
    
    ......
    @Override
    protected void onHandleIntent(Intent intent) {  
    
    //Check to see for storage permission
    if (ActivityCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
            == PackageManager.PERMISSION_GRANTED) {
     .....
     //Now create job queue
     ....
    //Fetch rows to download from table
    DownloadQuery downloadQuery = new DownloadQuery(DownloadIntentService.this);
    
    ArrayList<DownloadModel> downloadModelArrayList = downloadQuery.getDownload(DownloadContract.IFileDownloadStatus.NOT_DOWNLOADED,
                0, NUMBER_OF_CORES);
    //Check if queue contains any item
    if (downloadModelArrayList.size() > 0) {
    if (!executorService.isShutdown())
                        executorCompletionService.submit(new DownloadWorkerCallable(**Your download model from table to download**, DownloadIntentService.this));
    }
    .....
    //Don't forget to shutdown the executorService
    }
    }
    

这个DownloadWorkerCallable 正在实现实际下载文件的Runnable

【讨论】:

  • @Alexander 你说什么?
  • 谢谢。但启动服务后,用户可以随时添加新的下载项。在添加的每个下载项目上,我需要开始下载新的下载项目。如果我在您的示例中没有错,是在启动服务开始时获取所有下载项目?但是在我的代码中,服务启动后用户可以添加新的下载项
  • 一旦 IntentService 启动,它将继续运行,直到 task 或 onHandleIntent() 未完成。我在 onHandleIntent() 中获取项目。即使 onHandleIntent() 未完成,开始下载的新请求也会在队列中,并且 DownloadIntentService() 不会再次启动。还有另一种方法,您也可以从 onHandleIntent() 获取 do while(如果表中有更多项目)中的项目
  • 例如;用户点击了两首音乐,服务完成下载这些项目,服务停止。服务停止后一分钟,用户单击新音乐项目进行下载。我应该重新开始服务吗?
  • 它的优点是它会自动停止并进入队列。资源被释放。长时间运行的任务可以在 IntenetService 中执行,在您的情况下它正在下载。如果您深入了解我正在使用异步运行的 ExecutorService 的代码。 DownloadWorkerCallable 是它所消耗的。
【解决方案2】:

您应该使用 ThreadPool 或更好的 EventBus。 AsyncTask 不是多次下载的好选择。

【讨论】:

    【解决方案3】:

    这对你很有帮助。你在 android 中有 executeOnExecutor

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
     private void StartAsyncTaskInParallel(MyAsyncTask task) {
         if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
             task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
         else
             task.execute();
     }
    

    更多详情http://android-er.blogspot.in/2014/04/run-multi-asynctask-as-same-time.html

    您可以使用 5-6 个不同的网址同时下载。

    【讨论】:

      猜你喜欢
      • 2014-10-28
      • 2018-09-26
      • 1970-01-01
      • 2023-03-22
      • 2017-12-16
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      • 2013-04-14
      相关资源
      最近更新 更多