Download queue in Android - android

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.

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.

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.

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

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()

Related

Is it safe to start multiple AsyncTasks

In my app I have to download some JSON data from different JSON files. For this I ll use AsyncTask. I have 7 links for 7 JSON files. Which is correct way
1. to start an asyncTask from MainActivity and run a loop in it for 7 links
2. Or write an asyncTask that takes URL as parameter. And start this asyntask for each link.
Is starting multiple asyncTasks simultaneously same.
I think it is more safe to use Executor because AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) and server operations may take long time, If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and FutureTask.
Check this answer
https://stackoverflow.com/a/9906890/1826581
Also Check this link
http://developer.android.com/reference/android/os/AsyncTask.html
Definitely safe, works well in my app (6 tasks getting JSON in parallel). It's also much faster than doing it sequentially. You just have to make sure you start a new AsyncTask for each operation -- it's not possible to reuse an AsyncTask.
It is possible to run multiple async tasks parallely from HONEYCOMB version and also it is safe. So the way of implementing differs in honeycomb we have a concept called Thread Executor. Here is the example for Thread Executor.
Thread Pool
Executor
Thread.Executor Example

How should I make multiple http requests in android

Hey I am trying to make multiple http requests and wondering the best way to perform this in android. Currently I am using an IntentService with threads, however this doesnt work too well because onhandleintent returns before the threading is complete. Should I Switch to A regular service and start my own threads in there or would asyncTask be more approiate?
Thanks
Any time you deal with threads you're going to have to deal with synchronization. For example, when onHandleIntent() is called you may need to synchronize with your HTTP request thread(s) and wait for it to complete.
If you know ahead of time you will be doing this a lot it may be worth looking at something like ThreadPoolExecutor to save a bit on the pains of creating and tearing down threads. Again you will still need to synchronize your threads if you want to wait for their termination before moving on. Android has many ways of doing this including abstractions that make it fairly trivial to implement.
If you're already starting new threads anyway (whether directly or indirectly), then yes you should use a Service instead of an IntentService. The whole point of an IntentService is for it to handle threading for you.

Download files in queue in Android

How do I download multiple files in a queue one by one! I'm using this as a sample code, since.
I would be passing the URLs to download in Strings from my local DB dynamically.
Please let me know how to do that. I want the download to start as soon as the application launches. Kindly help me out!
Android Dev Type: Newbie
Purpose of Download Queue: To download multiple files from the server after in-app billing gets successful!
P.S.: I already referenced this question. But I'm not sure if that would solve my issue!
A good way of queuing up requests to be handled asynchronously, one at a time, is with an IntentService. If you have an IntentService which reads URLs from the supplied Intent, then all you have to do is create an Intent for each file you want to download, and send each Intent to the service,
Here is a good tutorial.
EDIT: I see you've already referred to a similar question, where the answer recommends IntentService. So, maybe you should use an IntentService. :)
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()
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.

AsyncTask v/s ThreadPoolExecutor for network request

I am working on a project where i need to hit a web service download the data which is JSON and will be represented in a list. And all the list items have there thumbnail url's which would be downloaded and displayed in the list item.
I have done the entire calling part with both a ThreadPoolExecutor and a AsyncTask.
But from a design perspective which is a better option out of:
1. ThreadPoolExecutor
2. AsyncTask
Few adv. of ThreadPoolExecutor:
1. User can define no. of concurrent threads that can be executed.
2. Cancelling all the request at once.
Few adv. of AsyncTask:
1. Internally it uses a ThreadPoolExecutor, however we cant define no. of threads that run simultaneously.
2. Cancelling a single request is easy.
3. Ability to attach and detach a task.
4. Updating the UI from doInBackground is simple.
I know more advantages of AsyncTask, however for a simple application like fetching data from a web service and later on fetching images.
Which would be more appropriate a AsyncTask or ThreadPoolExecutor? If you can provide a few reasons regarding your choice it would be helpful.
I have read a few article here on SO but none that compares the two. If there are any that i missed sorry for the trouble could you please post me the link for the same.
Thanks in advance.
I consider that AsyncTask is useful if you want to load thumbnail using a series "cascade-call": in the onPostExecute, you can start the next AsyncTask to download the next thumbnail.
But if you want to improve efficiency, I suggest using ThreadPoolExecutor. This is a sentence from developer.android.com:
Thread pools address two different problems: they usually provide
improved performance when executing large numbers of asynchronous
tasks, due to reduced per-task invocation overhead, and they provide a
means of bounding and managing the resources, including threads,
consumed when executing a collection of tasks. Each ThreadPoolExecutor
also maintains some basic statistics, such as the number of completed
tasks.
In conclusion, ThreadPoolExecutor was probably designed for cases such as your; for this reason, I suggest you this class.

Android Asynk Task

is a good practice to have an Asynk task with a loop like this inside?
while (true) {
check queue and request API
Because i need to wait for my Activities and service needs to comunicate with the APi.
Thanks
I am assuming the "queue" is a Java queue, perhaps a LinkedBlockingQueue. If so, that queue is unnecessary, as AsyncTask has a queue to go along with its thread pool.
So, the question is: what triggers things to go in the queue?
If the trigger is a user event (e.g., menu choice, button push), just have it launch an AsyncTask, or have it have a Service launch an AsyncTask. That work will be queued up by the AsyncTask system.
If the trigger is the passage of time (e.g., we want to check an external server every 10 minutes), I would use AlarmManager and consider switching from AsyncTask and a Service to using an IntentService.
I have a priority queue in order to select first the important calls to the API.
My program have two services:
One calls the API when a message is added to the queue. The call to the api is made by an Asinc Task in this way:
messages.add(request);
new DownloadApiTask().execute();
The other service is updating the local database. For that, i have a loop in which i call the first service in order to get data from the API. The basic structure is:
while ihave data to updload
mFirstService.putMessage(request).
Fine, the problem is i have a rejected Execution Exception every X calls, I think it can be because i invoke the asinc task every time i take a message.
For that, i was thinking in force to the asinck task to check the queue instead executing it.
I hope you can understand my problem.
Thanks

Categories

Resources