Android AsyncTask context behavior
I've been working with AsyncTasks in Android and I am dealing with an issue.
Take a simple example, an Activity with one AsyncTask. The task on the background does not do anything spectacular, it just sleeps for 8 seconds.
At the end of the AsyncTask in the onPostExecute() method I am just setting a button visibility status to View.VISIBLE, only to verify my results.
Now, this works great until the user decides to change his phones orientation while the AsyncTask is working (within the 8 second sleep window).
I understand the Android activity life cycle and I know the activity gets destroyed and recreated.
This is where the problem comes in. The AsyncTask is referring to a button and apparently holds a reference to the context that started the AsyncTask in the first place.
I would expect, that this old context (since the user caused an orientation change) to either become null and the AsyncTask to throw an NPE for the reference to the button it is trying to make visible.
Instead, no NPE is thrown, the AsyncTask thinks that the button reference is not null, sets it to visible. The result? Nothing is happening on the screen!
Update: I have tackled this by keeping a WeakReference
to the activity and switching when a configuration change happens. This is cumbersome.
Here's the code:
public class Main extends Activity {
private Button mButton = null;
private Button mTestButton = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mButton = (Button) findViewById(R.id.btnStart);
mButton.setOnClickListener(new OnClickListener () {
@Override
public void onClick(View v) {
new taskDoSomething().execute(0l);
}
});
mTestButton = (Button) findViewById(R.id.btnTest);
}
private class TaskDoSomething extends AsyncTask<Long, Integer, Integer>
{
@Override
protected Integer doInBackground(Long... params) {
Log.i("LOGGER", "Starting...");
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 0;
}
@Override
protected void onPostExecute(Integer result) {
Log.i("LOGGER", "...Done");
mTestButton.setVisibility(View.VISIBLE);
}
}
}
Try executing it and while the AsyncTask is working change your phones orientation.
Asked by: Kellan481 | Posted: 20-01-2022
Answer 1
AsyncTask is not designed to be reused once an Activity has been torn down and restarted. The internal Handler object becomes stale, just like you stated. In the Shelves example by Romain Guy, he simple cancels any currently running AsyncTask's and then restarts new ones post-orientation change.
It is possible to hand off your Thread to the new Activity, but it adds a lot of plumbing. There is no generally agreed on way to do this, but you can read about my method here : http://foo.jasonhudgins.com/2010/03/simple-progressbar-tutorial.html
Answered by: Emily308 | Posted: 21-02-2022Answer 2
If you only need a context and won't use it for ui stuff you can simply pass the ApplicationContext to your AsyncTask.You often need the context for system resources, for example.
Don't try to update the UI from an AsyncTask and try to avoid handling configuration changes yourself as it can get messy. In order to update the UI you could register a Broadcast receiver and send a Broadcast.
You should also have the AsyncTask as a separate public class from the activity as mentioned above, it makes testing a lot easier. Unfortunately Android programming often reinforces bad practices and the official examples are not helping.
Answered by: Julia963 | Posted: 21-02-2022Answer 3
This is the type of thing that leads me to always prevent my Activity from being destroyed/recreated on orientation change.
To do so add this to your <Activity>
tag in your manifest file:
android:configChanges="orientation|keyboardHidden"
And override onConfigurationChanged in your Activity class:
@Override
public void onConfigurationChanged(final Configuration newConfig)
{
// Ignore orientation change to keep activity from restarting
super.onConfigurationChanged(newConfig);
}
Answered by: Dainton931 | Posted: 21-02-2022
Answer 4
To avoid this you can use the answer givin here: https://stackoverflow.com/a/2124731/327011
But if you need to destroy the activity (different layouts for portrait and landscape) you can make the AsyncTask a public class (Read here why it shouldn't be private Android: AsyncTask recommendations: private class or public class?) and then create a method setActivity to set the reference to the current activity whenever it is destroyed/created.
You can see an example here: Android AsyncTask in external class
Answered by: Elian676 | Posted: 21-02-2022Similar questions
multithreading - Android AsyncTask and Thread different behavior
I'm posting this question because I think this behaviour is really strange.
I wrote an AsyncTask to download a file from the web. This AsyncTask is declared in a separate class so I can call it from everywhere. I noticed that during the AsyncTask execution my app was reacting very slowly, that is strange since the moment that, by definition, an AsyncTask's d...
multithreading - Android : can AsyncTask return in another thread than UI thread?
Android documentation says that AsyncTask postExecute() is called on the UI thread. I was under the impression that postExecute() was called from the Thread where execute() was called : I have been using an AsyncTask in a background Service with its own thread, and postExecute() was called in the service thread, not the main thread.
However, I recently had an issue with the postEx...
multithreading - Android AsyncTask and Thread life cycle
I am a little confused about AsyncTask and Thread life cycle.
What happens to a processes threads when the OS enters the OnStart/OnStop and onResume/onPause sequences.
Are the threads affected by this sequence.
I ask this question because I am using sockets in the threads and killing the threads will kill the tcpip connections as well (I assume).
If the thredas are not killed then how do I 'reconnect' to them especially as...
multithreading - Android AsyncTask issue
I've developed an application that takes content from the internet and shows it accordingly on the device's screen . The program works just fine , a little bit slow . It takes about 3-4 seconds to load and display the content . I would like to put all the code that fetches the content and displays it in a background thread and while the program is doing those functions , I would like to display a progress dialog. Could you...
multithreading - Android: Reading multiple rss feeds as fast as possible using asynctask / threads
I have an app that reads about 3-5 rss feeds and present the headlines on the UI. I've put the reading code inside an asynctask to keep the UI responsive. But my code reads the feeds one at a time and I would like to read the 3 rss feeds at the same to see if I can speed up the parsing process and present the headlines faster on the UI.
I've tried to use threads - but then I ran into the problem that I didn't knew...
multithreading - Android AsyncTask Threading
Dear Stackoverflow programmers,
I've made an app a few months ago and it is working flawelessly. However, on the new Android ICS it started crashing. I looked it up and i get a Network On Main Thread Exception. I tried to rewrite my code but i can't get it to work the way it did.. I tried AsyncTasking but that also didn't work.. Please can someone help me out??
my code: (if you also need XMLFunctions.class ...
multithreading - Android AsyncTask threads limits?
I am developing an application where I need to update some info every time user logs in to the system, I also use database in the phone. For all those operations (updates, retrieving data from db and etc.) I use async tasks. As up till now I didn't see why I shouldn't use them, but recently I experienced that if I do some operations some of my async tasks simply stop on pre-execute and don't jump to doInBackground. That wa...
multithreading - Working of Handlers and Asynctask in android?
I wanted to know if any one can explain the control flow of the following tutorial :
http://www.vogella.de/articles/AndroidPerformance/article.html
I am not aware of how does Runnable and post() method of Handler work?
Thanks
Sneha
multithreading - Android wait AsyncTask to finish
I have a function, AppHelper.isOnline(Context context), I call in various parts of my application to check that a session didn't timeout before making an HTTP request.
public void onClick(View v) {
Intent intent = null;
switch (v.getId()) {
case R.id.buttonPagamenti:
if (AppHelper.isOnline(this))
{
//here AppHelper.isOnline should...
multithreading - Update Activity class from complete different class that extends AsyncTask in Android
Have done some reading already but have not found a thread/article I felt I understood to help me with my issue.
In an activity in my Android application I have a simple ListView that contains the title of images and a ProgressBar for each image that needs to be downloaded. The logic to download these images are and must be in a separate non activity classes that fire off each image that needs to be downloaded in i...
multithreading - Android AsyncTask crash
I'm extending AsyncTask and in my doInBackground() I get a button view using findViewById and when I call button.performClick() my app crashes.
Any idea why?
this is the logcat:
E/AndroidRuntime(604): FATAL EXCEPTION: AsyncTask #2
E/AndroidRuntime(604): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime(604): at android.os.AsyncTask$3.done(AsyncT...
multithreading - Android thread in background
I'm developing an Android application and I have a problem running a new thread in background.
I make a class with this code:
public class Downloader implements Runnable {
private Vector <DownloadRequest>messages = new Vector<DownloadRequest>();
static final int MAXQUEUE = 5;
ApiRequest mApi;
public void run() {
try {
while ( true ) {
getMessage();
...
multithreading - Android: running a thread in background
is there any way to leave a thread in background when i close the app in android? I read about a Service but implementing it is too much than i need. Thanks
multithreading - two android threads and not synchronized data
i have a (perhaps stupid) question:
im using 2 threads, one is writing floats and one is reading this floats permanently. my question is, what could happen worse when i dont synchronize them? it would be no problem if some of the values would not be correct because they switch just a little every write operation. im running the application this way at the moment and dont have any problems so i want to know what co...
multithreading - Update UI in the main activity through handler in a thread (Android)
I try to make several connection in a class and update the multiple progressbar in the main screen.
But I've got the following error trying to use thread in android :
Code:
05-06 13:13:11.092: ERROR/ConnectionManager(22854): ERROR:Can't create handler inside thread that has not called Looper.prepare()
Here is a small part of my code in the main Activity
public class Act_Main extends Lis...
multithreading - Simple Android Binary Text Clock
I want to create a simple android binary clock but my application crashes.
I use 6 textview fields: 3 for the decimal and 3 for the binary representation of the current time (HH:mm:ss).
Here's the code:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class Binary extends Activity implements Runnable...
multithreading - Android 2.1: Multiple Handlers in a Single Activity
I've more than one Handlers in an Activity. I create all the handlers in the onCreate() of the main activity. My understanding is the handleMessage() method of each handler will never be called at the same time because all messages are put in the same queue (the Activity thread MessageQueue). Therefore, they will be executed in the order in which are put into the Queue. They will also...
multithreading - Android: Quitting the Looper?
I have a thread I use to periodically update the data in my Activity. I create the thread and start a looper for using a handler with postDelay(). In onDestroy() for my activity, I call removeCallbacks() on my handler.
Should I then call handler.getLooper().quit()? Or not worry about it and let the OS deal with it? Or would it just run forever then, consuming CPU cycles?
multithreading - handling activity destruction in multithreaded android app
I have a multithreded app where background threads are used to load data over network or from disk/db. Every once in a while user will perform some action e.g. fetch news over network, which will spawn a background AsyncTask, but for some reason user will quit the app (press back button so that activity gets destroyed). In most such scenarios, I make appropriate checks in the background thread after it returns from n/w i/o...
multithreading - android: pausing an activity until another finishes
When my app starts, it checks to see if it has stored login credentials. if it doesn't, it starts another activity to prompt the user for those credentials. My problem is, that when the prompt activity is started, the first activity continues execution and ends up with null pointers because the prompt activity has not yet returned the needed data
public void onCreate(Bundle savedInstanceState) {
super.o...
multithreading - Android - Question on postDelayed and Threads
I have a question about postDelayed. The android docs say that it adds the runnable to the queue and it runs in the UI thread. What does this mean?
So, for example, the same thread I use to create my layout is used to run the Runnable?
What if I want it as an independent thread that executes while I am creating my layout and defining my activity?
Thanks
Chris
Still can't find your answer? Check out these communities...
Android Google Support | Android Community | Android Community (Facebook) | Dev.io Android