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.
Related
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.
My Problem: Is it possible to prevent an activity to call OnResume() when it is being created? As I saw after the OnCreate() and onStart() method runs, the next one is the onResume(), although I only want to have it when I resume the activity from the paused state.
Why do I need this: I launch my activity (FragmentActivity, so lets say OnPostResume() ) starting with a thread which takes about 2-3s to be ready getting data from an external database. After the thread is done, I call a method which needs these data and I want to call it everytime that activity gets visible. The thread runs only when the FragmentActivity is created (onCreate()), and I cannot put the method into the onResume() because onResume() would be running way before the thread would finish its task. So it would receive not-ready data.
Anyone has a better idea?
Not sure of the exact application of this but I'll make a suggestion.
If you use an AsyncTask, you can send it off to get the data you need and in the onPostExcecute() method you can call your method that requires the data or update the view as needed. (It runs on the UI thread)
If you happen to already have the data you need in certain scenarios you could also bypass the AsyncTask and directly update the view.
This AsyncTask can be triggered in the onResume() method.
If I'm missing something, please let me know and I can adjust my suggestion.
I didn't understand the purpose of this, but here's a possible solution:
If you only wish to get the even of onResume on states that didn't have the onCreate before, just use a flag.
In the onCreate, set it to true, in the onResume check the flag (and also set it to false). if it was true, it means the onCreate was called before.
I personally would prefer to check if the result available, rather than always executing the getter-code in onResume. If the user somehow resumes your activity before the background thread is finished, you'd have a call on onResume, but don't want to display a result.
Maybe it would be a good idea to calculate/fetch the values in the thread, and let the thread return immediately (and cause the values to get filled in) if the values are already cached somewhere. That way you'd only have one entry point (the thread) for updating your UI instead of two (the thread and the onResume method).
I need to implement auto-login process from an activity. Also I need to show ProgressDialog while logging in. I use AsyncTask for login process, because I haven't succeeded to show ProgressDialog in other way, and I execute the mentioned AsyncTask in onCreate. I read that all the code which is executed after doInBackground must be written in onPostExecute, but I have code in onResume. The onResume is launched when AsyncTask hasn't finished its execution yet. Is it possible to launch onResume only after AsyncTask is finished? Or is it possible to execute other functions after AsyncTask is finished (in general)?
Is it possible to launch onResume only after AsyncTask is finished?
No, you need to follow the Activity Lifecycle. And the AsyncTask is asynchronous so that it can run while your UI can still do other things. What you can do is put the code that is in onResume() that you want to run after the task has finished in your onPostExecute() method. There are other options but without seeing the code you are trying to run, this would be my suggestion.
Or is it possible to execute other functions after AsyncTask is finished (in general)?
Yes. You can put that code in another Activity method and call that from onPostExecute()
You also can use getStatus() method of AsyncTask to run code based on the Status of your AsyncTask
Short Answer: No.
If you check the developer android website or this image, you'll check that OnResume() after the Activity is loaded, either after created, paused or restarted. In my case, I have that verification done in OnResume().
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.
I have an Activity that retrieves information from a remote server and displays it in a TableLayout.
The function that retrieves the information from the server has its own timeout, and exception is thrown when the timeout gets exceeded.
Now, when the activity is loaded, I want the function to be fired, and a progressDialog to be shown while the function works, and to be hided if the function is done working, or if a timeout exception was thrown.
The problem: I've put the code that do all the functionality described above in the onCreate() function. Nothing is shown on the emulator screen, since the onCreate() function hasn't finished running...
I've also tried to put the code in the onStart() function... same unwanted results...
I'm trying to avoid using of threads, because the functionality needs many variables that the thread will not has access to them...
How can i implement the wanted behavior??
Thanks.
Use AsyncTask with ProgressDialog bounded:
http://it-projects.spb.ru/?p=150&lang=en
Create a class implementing Runnable and put all your load logic in there. Call a function in the activity when finished (lets say onFinished(params...))
Create a UI Handler and get the handler to update UI in onFinished(params...)
Create a thread in onCreate and start it there to call your Runnable.