Is it safe to start multiple AsyncTasks - android

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

Related

Android - AsyncTask for continuous thread

Is it safe to use an AsyncTask class object without ever using get, to create a constantly running thread? (etc. involving a while loop)
From javadoc :
AsyncTasks should ideally be used for short operations (a few seconds at the most.) 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 package such as Executor, ThreadPoolExecutor and FutureTask.
So, no: it is not recommended.
If you wanna run a long process or need the task run in background, you need a Service instead an AsyncTask.

Creating threads from inside a worker thread in Android

In my app, I need to make a number of TCP socket calls.
To be able to do this, I have to do the following steps:
1. convert my data/command into a byte stream
2. create socket and send command and receive response
3. parse response and store for UI to use.
Now I have created a background thread to be able to do all three steps.
But in my socket client also I want to create a new thread for each new command (Step# 2)
So that would mean that I have a number of worker threads inside the common worker thread for all the three above steps.
So, would it be ok to use Async task for step #2 which is already taking place in a worker thread. Or do I use normal thread in this case.
One might wonder why am i not achieving all three steps in one worker thread.
The point is that even if I create just one worker thread for all the socket commands, there is a possibility that the initial request for step 1 might itself come from a worker thread.
Hence, I cannot just assume that the call is from Main UI thread.
Also, I wanted to ask whether it is not recommended to create your own worker threads in android and why?
Thanks,
Sunny
Form your first 2 paragraphs i understand you want to establish some communication via sockets. i dont believe it would be a good approach to create a thread per command as thread itself and opening/closing sockets are expensive operations.
i would suggest creating only one thread for opening and monitoring/writing/reading data to/from socket. if these commands are frequent than maintaining one socket alive is more appropriate than frequently opening/closing sockets. optionally i would create an extra thread for doing the extra work of serializing/deserializing commands (if they r time-consuming).
One might wonder why am i not achieving all three steps in one worker thread. The point is that even if I create just one worker thread for all the socket commands, there is a possibility that the initial request for step 1 might itself come from a worker thread.
I dont think it would make a big difference in your design approach where the requests come from.
Hence, I cannot just assume that the call is from Main UI thread. Also, I wanted to ask whether it is not recommended to create your own worker threads in android and why?
Android provides some very good generic classes such as AsyncTask and HandlerThread for general purpose usages but anyone is free to create a worker thread if the above ones do not fit the design requirements. Personally i create my own worker threads if i deal with socket programming.
I would suggest taking a look at Java NIO library specifically Selectors, and SocketChannel classes
You cannot use AsyncTask for that.
AsyncTasks can only be instantiated and executed on the UI thread.
You can, however, use standard threads.
class MyThread {
#override
public void run() {
......
// when needed - span a new working thread fro within old one
new MyOtherThread(...).start();
}
}
No problems here.
if you feel the number of threads you are spawning may go out of control, it is a smart idea to use a thread pool. The java.util.concurrent package has several, e.g.
ThreadPoolExecutor.
Finally, and I have give this recommendation several times before, if your task
is to transmit a large amount of small object using a multi threaded architecture,
using Volley is probably the most effective way to go.
Good luck.

asynctask doInBackgound() not running if there's a asynctask already running

When the user logs in into my app. I am starting an asynctask to maintain the user session. And that async task is running indefinitely till the user logs out. My problem is that when I try to start other asynctasks, their doInBackground() method is never executed.
I read somewhere that if an async task is already running, we cannot start new async task. I can confirm this because when i removed the user session async task, it worked properly. Is there a workaround?
P.S.: I have already used executeOnExecutor() method. but it didn't help.
For potentially long running operations I suggest you to use Service rather than asynctask.
Start the service when the user logs in
Intent i= new Intent(context, YourService.class);
i.putExtra("KEY1", "Value to be used by the service");
context.startService(i);
And stop the service when the user logs out
stopService(new Intent(this,YourService.class));
To get to know more about Service you can refer this
Service : Android developers
Service : Vogella
To know more about asynctask vs service you can refer this
Android: AsyncTask vs Service
When to use a Service or AsyncTask or Handler?
I read somewhere that if an async task is already running, we cannot start new async task.
Yes,That is fact that you can't run more then 5 (five) AsyncTaskat same time below the API 11 but for more yes you can using executeOnExecutor.
AsyncTask uses a thread pool pattern for running the stuff from doInBackground(). The issue is initially (in early Android OS versions) the pool size was just 1, meaning no parallel computations for a bunch of AsyncTasks. But later they fixed that and now the size is 5, so at most 5 AsyncTasks can run simultaneously.
I have figure out Some Threading rules and i found one major rule is below ,
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
What is definition of AsyncTask?
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
How & Where use it?
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.) If you need to keep threads running for long periods of time, it is highly recommended to use it.
Why you can't use multiple AsyncTask at same time ?
There are a few threading rules that must be followed for this class to work properly:
The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
Running multiple AsyncTasks at the same time — not possible?
Test sample of parallel excution of AsyncTasks
Try Executor
You should go with Executor that will mange your multiple thread parallel.
Executor executor = anExecutor;
executor.execute(new RunnableTask1());
executor.execute(new RunnableTask2());
...
Sample Example 1
Sample Example 2
Just like a few others here, I object to the premise of the question.
Your core problem is that you are using an AsyncTask to perform a task beyond its scope. Others have noted this too. Those who offer solutions that can mitigate your problem through low-level threads (even java.util.Concurrent is low-level which is why Scala uses Akka actors as an abstraction), Service, etc. are quite clever, but they are treating the symptom rather than curing the disease.
As for what you should be doing, you are not the first to want to maintain a user session in an Android application. This is a solved problem. The common thread (no pun intended) in these solutions is the use of SharedPreferences. Here is a straightforward example of doing this. This Stack Overflow user combines SharedPreferences with OAuth to do something more sophisticated.
It is common in software development to solve problems by preventing them from happening in the first place. I think you can solve the problem of running simultaneous AsyncTasks by not running simultaneous AsyncTasks. User session management is simply not what an AsyncTask is for.
If you are developing for API 11 or higher, you can use AsyncTask.executeOnExecutor() allowing for multiple AsyncTasks to be run at once.
http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor(java.util.concurrent.Executor, Params...)
I'll share with you, what we do on our App.
To keep user Session (We use OAuth with access/refresh tokens), we create a Singleton in our Application extended class. Why we declare this Singleton inside the MainApplication class? (Thats the name of our class), because your Singleton's life will be tided to the Activity that has created it, so if your Application is running on low memory and Garbage Collector collects your paused Activities, it will release your Singleton instance because it's associated to that Activity.
Creating it inside your Application class will let it live inside your RAM as long as the user keeps using your app.
Then, to persists that session cross application uses, we save the credentials inside SharedPreferences encrypting the fields.
yes starting 2 or more asynctasks simultaneously may cause issues on some devices. i had experienced this issue few months back. i could not predict when the 2nd asyncTask would fail to run. The issue was intermittent may caused by usage of memory as i was executing ndk code in asynctask. but i remember well that it depended on memory of device.
Similar question had been asked before. I would post the link for the similar question.
AsyncTask.executeOnExecutor() before API Level 11
Some users suggest go for Service. My advice is don't go for that path yet. Using service is much more complicated. Even you are using service, you still have to deal with threading, as
Note that services, like other application objects, run in the main
thread of their hosting process. This means that, if your service is
going to do any CPU intensive (such as MP3 playback) or blocking (such
as networking) operations, it should spawn its own thread in which to
do that work....
If we can solve a problem in elegant way, don't go for the complicated way.
I would suggest that, try one of the APIs in java.util.concurrent as suggested in below
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.) 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.
I can't give you any code example so far, as I do not know how you design your session managing mechanism.
If you think your long running session managing task shouldn't bind to the life cycle of your main application life cycle, then only you might want to consider Service. However, bear in mind that, communication among your main application and Service is much more cumbersome and complicated.
For more details, please refer to http://developer.android.com/guide/components/services.html, under section Should you use a service or a thread?

Difference between AsyncTask and Thread/Runnable

I have question which puzzles me.
Imagine I wanna do something in another thread, like fetching GPS/Location stuff, which as recommended in the SDK documents, must use a background thread.
So here is the question: What's the difference between
Creating a Thread in background via AsyncTask AND
Creating Thread thread1 = new Thread(new Runnable() ... and implementing run()?
AsyncTask is a convenience class for doing some work on a new thread and use the results on the thread from which it got called (usually the UI thread) when finished. It's just a wrapper which uses a couple of runnables but handles all the intricacies of creating the thread and handling messaging between the threads.
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
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.) 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.
An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
The Runnable interface is at the core of Java threading. The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread.
Also if I quote from this blog:
if you need SIMPLE coding use AsyncTask and if you need SPEED use traditional java Thread.
Key differences:
AsyncTask is an asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. It can't be done with normal thread unless you use Handler on UI Thread and post a message OR directly change attribute of an object by implementing proper synchronization.
As recommended by developer guide regarding Thread performance,
There are a few important performance aspects to keep in mind. First, by default, an app pushes all of the AsyncTask objects it creates into a single thread. Therefore, they execute in serial fashion, and—as with the main thread—an especially long work packet can block the queue. For this reason, we suggest that you only use AsyncTask to handle work items shorter than 5ms in duration..
But normal Thread can be used for long running tasks.
Plain java Threads are not much useful for Android unlike HandlerThread, which has been provided by Android framework.
Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.
Refer to below post to know more details:
Handler vs AsyncTask vs Thread
Also take in count that starting on Android v4.04, you can't have more than one AsyncTasks at a time, unless you lose compatibility with lower versions. Be aware!
AsyncTask deprecated with api level 30. Using thread/runnable is convenient
One obvious drawback for AsyncTask class is that after Android 3.0 asynctasks are executed according to the sequence of the start time. that is tasks are executed one by one, unless you execute the task by calling 'executeOnExecutor(Executors.newCachedThreadPool())'. this method would create your own thread pool.
Better to use the new Job Scheduler in the support library.

Download queue in 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()

Categories

Resources