What happens to running AsyncTasks when the Activity changes? - android

While Network Operation is running in Asynctask, If user press the Back button and switch to another activity what will happen to Asynctask which is running in background?
AsyncTask Process automatically Kill by OS?
Async Task complete it's entire operation?

If you start an AsyncTask inside an Activity and you rotate the device,the Activity will be destroyed and a new instance will be created.
Similarly if user navigate to another activity,current activity will be destroyed or go in background activity stack and new activity would be in foreground.
But the AsyncTask will not die. It will go on living until it completes.
And when it completes, the AsyncTask won't update the UI of the new Activity. Indeed it updates the former instance of the activity that is not displayed anymore. This can lead to an Exception of the type java.lang.IllegalArgumentException: View not attached to window manager if you use, for instance, findViewById to retrieve a view inside the Activity.

AsyncTask is an abstract Android class which helps the Android applications to handle the Main UI thread in efficient way. AsyncTask class allows us to perform long lasting tasks/background operations and show the result on the UI thread without affecting the main thread.
1. AsyncTask processes are not automatically killed by the OS. AsyncTask processes run in the background and is responsible for finishing it's own job in any case. You can cancel your AsycnTask by calling cancel(true) method. This will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object) method is called instead of onPostExecute() after doInBackground() returns.
2. After completion of it's operation, the background thread it's working on is stopped. AsyncTask has an onPostExecute() which is called once your work is finished. This method is called after doInBackground() method completes processing. Result from doInBackground() is passed to this method.

AsyncTask will still run and try to post result on Zombie Activity. Best is to user AsyncTaskLoader.

Related

Android AsyncTask called "multiple" times

i'm fairly new to android programming. I have a main activity that gets data from a DB through a service handler (url). I want to insert data as well, but on a different activity, and i want my main activity to be up to date each time its been called (onresume(),onrestart()).
I've found this on the Android API reference about AsyncTask:
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
Does that mean that i cannot call the AsyncTask whenever the activity resumes, or that i cannot have multiple "instances" of the AsyncTask running at the same time?
It literally means, that while AsyncTask is running, you cannot launch it again.
In your MainActivity.class you have line:
task.execute();
if task either is finished or not and you call the method again then exception will be thrown.
And put this method in onResume() is a good practice.
Only one thing to notice is: if you put in onRestart() remember, this callback works when you change configuration, but it will not be called if you Create activity.
The doc about lifecycle of an Activity.
Does that mean that i cannot call the AsyncTask whenever the activity resumes, or that i cannot have multiple "instances" of the AsyncTask running at the same time?
It means you cannot call the execute method twice on the same AsyncTask instance regardless it is completed or not.

How to cancel AsyncTask or all AsyncTask including nested AsyncTasks from same Activity?

I have activity use AsyncTask to open cursor than spawns children AsyncTask to render items read with cursor.
Activity executes on cursor AsyncTask but not see children AsyncTask for items.
How to cancel all running AsyncTask tasks (including nested) for specified Activity?
How to cancel all running children AsyncTask tasks for specified AsyncTask (if it possible at all)?
I want to stop all tasks on new command from interface to not corrupt views.
There's no manager for the AsyncTask you execute.
You'll have to keep track of all the new instances of the AsyncTasks you've created and close them with cancel(boolean mayInterruptIfRunning) method.
Pay attention that canceling the Task won't stop it in the middle. You'll have to check in your doInBackground - isCanceled()
If your AsyncTask are running loops, then you can check for a common flag (maybe an attribute of some singleton, like the Application class itself, or your activity). As soon as this flag becomes true, then your Tasks will exit the loop

What is the common practice to handle relation between Activity and Thread

I have the following situation
I spawn a long running user thread (Thread) from an Activity.
I press soft back button. So, the Activity was destroyed.
I launch the same Activity again. Note, the previous launched Thread is still running.
In order for me to prevent the Activity from launching another same Thread while the previous Thread is still running, here is what I am doing
After I launch the Thread, I will store it into a static variable. So, next time when I try to launch a same thread, I will check against the liveness of previous thread through the static variable. Is this a good practice? What is the best practice to overcome this?
Note, the user thread is holding reference to the Activity which launched it. However, the Activity might destroyed when user press on soft back button. So, when I launch the new Activity again, the thread is not aware of that, and it is still referring to old Activity. So, when user thread try to access any members of the old Activity, crashes will happen as the Activity already being destroyed. What is the best practice to overcome this?
The best way to overcome this is to use an AsyncTask instead. If the Activity is destroyed while the task is executing, the AsyncTask (and its underlying Thread that is performing the operation) will continue its execution until doInBackground() has completed. If the Activity is null by the time onPostExecute is called, you won't run into any NullPointerExceptions for the reasons stated in this blog post.
If you want to immediately cancel the task if the user "backs out" of the Activity, you can call mTask.cancel() on your AsyncTask in your Activity's onDestroy method.
If you don't want to immediately cancel the task if the user "backs out" of the Activity, then your long-term operation doesn't sound like it is specific to any Activity instance. In this situation, it is often advised to use a Service instead.

Will thread be killed before the activity finishes in Android?

In Android, I have a thread that initializes a global variable. The thread starts when the activity starts. If the activity finishes before the thread initialized the global variable will the thread still run in the background to complete its job or it will be killed as the activity finishes?
The Activity finishing is part of the main execution/UI thread in android. When you spawn a new thread, and perform operations on that thread, it works as a separate entity from the main UI thread.
Hence, to answer your question - The thread will still run in the background to complete its job.
However, a word of caution. If within the run() method, you are using some objects that are part of the activity class that just got terminated, you can run into null pointer exceptions.

Calling asynctask from runnable

Is it possible to execute an AsyncTask from Runnable? in my experience it can be done, but not safely. When my app first runs my AsyncTask runs fine from the Runnable. But when the app is moved to the background, then brought back forward I get "Can't create handler inside thread that has not called Looper.prepare()".
Here's what I'm trying to do:
I'm using MapView and invoking runOnFirstFix(Runnable) within onCreate. My Runnable calls an AsyncTask to perform a web service call which returns some data based on the location.
I move the app to the background (by tapping the home button), after some time I bring my app forward again and I'm getting the exception at the point where I'm invoking execute() on my AsyncTask.
First of all, why is runOnFirstFix being executed again? Secondly, why is it causing the exception the second time around?
I'm guessing that there is some part of the lifecycle that I don't understand.
Thanks.
It wasn't initially obvious to me that the AsyncTask needed to be called from the UI thread. So when runOnFirstFix ran the second time it was from withing a Runnable which wasn't on the UI thread. To solve the problem I simple created another Runnable inside the first to run the AsynchTask.
And the reason my runOnFirstFix seemed to be called twice was simply because I was creating a new instance of it.

Categories

Resources