8

What's the best way to implement a download queue in Android?

I suspect there might be some platform classes that might do most of the work.

hpique
  • 119,096
  • 131
  • 338
  • 476

4 Answers4

17

What's the best way to implement a download queue in Android?

Use an IntentService. It supplies the queue and the background thread for you, so all you have to do is put your download logic in onHandleIntent(). See here for a sample project demonstrating this.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 1
    Hello Commonsware, Above metion example is not a download queue. its just download image in background. what if i have 20 image to download? – Krishna Shrestha May 18 '15 at 10:56
  • 1
    @chrish: "Above metion example is not a download queue" -- yes, it is. I just happen to only be invoking it once. "what if i have 20 image to download?" -- call `startService()` 20 times, each with the information needed for the `IntentService` to know what to download. While one command is processing, the others will queue up inside of `IntentService`, waiting for their turn. If you want to have a download queue with multiple threads working off the queue, create your own `Service` that uses a `ThreadPoolExecutor` and calls `stopSelf()` when the queue empties. – CommonsWare May 18 '15 at 10:59
  • @CommonsWare How we can now that service finished downloading all 20 files? Okey, I can easily call startService 20 times, but how I can now that service finished all of them? – Zookey Nov 23 '16 at 15:09
  • 1
    @Zookey: Have the service use an event bus to publish results of the download request (success/failure). Have whoever knows that there are 20 files waiting to be downloaded subscribe on that event bus and keep count. – CommonsWare Nov 23 '16 at 15:12
  • Whats the problem in using download manager and broadcast receiver with queue stored in db as mentioned here https://stackoverflow.com/a/27590425/1769274 – Nabeel K Dec 04 '17 at 09:17
  • @NabeelK: `DownloadManager` has many limitations. It had even more limitations back in 2010, when I wrote this answer. But, if you can live with `DownloadManager`'s limits, you are welcome to use it. – CommonsWare Dec 04 '17 at 11:30
  • @CommonsWare thanks for your prompt reply. In this method how will I show progress for each download in my home screen ? – Nabeel K Dec 04 '17 at 12:58
  • @NabeelK: I suggest that you ask a separate Stack Overflow question where you explain what "this method" is and what "show progress for each download in my home screen" means. – CommonsWare Dec 04 '17 at 13:14
  • Sorry, by "this method" I meant using `IntentService`. – Nabeel K Dec 04 '17 at 13:35
2

I would suggest looking at the java.util.concurrent package and more specifically read up on Executors

You can create an ExecutorService which would only run 'n' number of Runnable objects at a time and would automatically queue up the rest of the tasks. Once one of the threads being executed finishes execution it picks up the next Runnable object in queue for execution.

Prashast
  • 5,645
  • 3
  • 30
  • 31
2

Using an IntentService will make it quite difficult to support cancellation. It's just something you need to be aware of. If you can, it's API Level 9, you will be better of using http://developer.android.com/reference/android/app/DownloadManager.html

1

From API 11 up, a good approach is to use a FixedThreadPool with async tasks. Do once:

ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(3);

Where 3 is the number of downloads you want to run at the same time. It will queueu the task if there are already 3 downloads running, and automatically handle the task later. Launch your async tasks with:

yourAsynTask.executeOnExecutor(threadPoolExecutor, params);

Params is probably the url you wish to connect to. You can read it out in the onPostExecute of your asynctask, and connect to the server using a HttpURLConnection.

Make sure you call down this on shutdown:

threadPoolExecutor.shutdown()
Frank
  • 12,010
  • 8
  • 61
  • 78