问题描述
我有一个活动,它有两个列表视图。 第一listview有音乐。 第二个列表视图显示下载项,每个下载项显示进度百分比的进度条。 如果用户单击音乐项目,我将下载项目添加到第二个列表视图中,并使用AsyncTask开始下载文件。 用户可以单击多个音乐,这意味着可以同时下载多个文件。 我可以使用AsyncTask下载文件。 但是我想下载服务中的文件,因为即使应用程序关闭,下载也必须继续。
我不知道如何与服务同时下载多个文件。 我应该遵循哪些步骤? 有为此的任何教程吗?
1楼
我已经在其中一个生产应用程序中实现了相同的功能:
- 创建一个表以添加要下载的项目。 排序应基于添加要下载的项目的时间。 将此视为队列。 还要添加一列以检查文件是否已经下架。 如果已下载,则将其从队列中删除。
-
创建一个
IntentService
,即使应用程序已关闭,它也将负责在后台下载数据。 该Service
应保持运行,直到表队列不为空。 仅当添加新项目或网络连接状态从无效变为活动时,才应启动它。 在此Service
您应该检查队列是否为空。 如果为空,则从表中获取N行以添加到队列(ExecutorService
)中以进行下载。 要检查网络状态变化,请使用?LocalBroadcastManager
创建BroadcastReceiver
。 现在,您可以在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
。
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();
}
有关更多详细信息,请访问
您可以使用5-6个不同的网址同时下载。