If I remember correctly, if you post a Runnable to a Handler instance
(AsyncTask does this), the messages(/Runnables) are posted back to
your application on the main UI-thread, regardless whether your
activity is active or destroyed.
You do have to check *which* Activity instance is active (or maybe
even none) when the onPostExecute is being called. For this, i use a
static reference to my current activity:
class MyActivity extends Activity {
...
// A single static reference to the currently active
// activity (note: this is only fool-proof when only one
// instance at the same time (for a process) can be active)
private static MyActivity ACTIVE_INSTANCE = null;
...
@Override
protected void onCreate() {
ACTIVE_INSTANCE = this;
super.onCreate();
...
}
@Override
protected void onDestroy() {
...
super.onDestroy();
ACTIVE_INSTANCE = null;
}
...
}
And from within your onPostExecute, you'd use ACTIVE_INSTANCE to show
any updates in the user-interface. Be sure to check if it is null or
not.
Note that is has bitten me in the past a few times using an inner
class that is a subclass of AsyncTask and implicitly referring back to
the Activity that started the AsyncTask. e.g. (ommitting the
generics):
public MyActivity extends Activity {
private TextView mMyTextView;
...
...
public void someMethod(SomeInput input) {
AsyncTask runInBackground = new AsyncTask() {
protected Result doInBackground (Params... params) {
... do your background stuff here ...
}
protected void onPostExecute (String result) {
...
mMyTextView.setText(result);
...
}
};
runInBackground.execute(input);
}
...
...
}
The problem was that mMyTextView refers to the TextView in an Activity
that may have been destroyed when onPostExecute is called. Instead:
public MyActivity extends Activity {
private TextView mMyTextView;
...
...
private static MyActivity ACTIVE_INSTANCE = null;
...
@Override
protected void onCreate() {
ACTIVE_INSTANCE = this;
super.onCreate();
...
}
@Override
protected void onDestroy() {
...
super.onDestroy();
ACTIVE_INSTANCE = null;
}
...
public void someMethod() {
AsyncTask runInBackground = new AsyncTask() {
protected Result doInBackground (Params... params) {
... do your background stuff here ...
}
protected void onPostExecute (String result) {
if (ACTIVE_INSTANCE == null)
return;
...
ACTIVE_INSTANCE.mMyTextView.setText(result);
...
}
};
runInBackground.execute(input);
}
...
...
}
On Oct 19, 1:53 pm, szabolcs <[email protected]> wrote:
> Hello,
>
> Am I correct in assuming that any callbacks of the AsyncTask that are
> run on the UI thread (e.g. onPostExecute) are 'queued' during a screen
> rotation?
>
> Example:
> 1. an AsyncTask is executed
> 2. a screen rotation is initiated
> 3a. AsyncTask's doInBackground() finishes, or
> 3b. AsyncTask's publishProgress() is called before the rotation is
> done
> --- now what happens here? is it
> 4. screen rotation is completed before the 'pending'
> AsyncTask.onPostExecute/onProgressUpdate is run?
>
> I assumed so, since looking at DDMS, it seems like the rotation does
> NOT create a new UI thread, in which case any calls to the UI must be
> stalled while the UI thread is busy completing the rotation, right?
>
> It would be great if this was true, since it would save me from having
> to do a bunch of synchronization work for posting back from AsyncTasks
> (I am keeping the tasks running during a rotation) - at least so I
> think..
>
> Thank you for any tips on this,
>
> -szabolcs
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---