You can use a class like this that attaches/detaches the Activity.
This is not my invention, but I cannot find the original thread:
import android.os.AsyncTask;
/**
* Android's ASyncTask is very useful, but using a background thread
can be though in the context of the Activity
* lifecycle, at least if you'd prefer your background task to not
restart with an orientation change. This version of
* ASyncTask tries to alleviate those pains. The idea is that you
"retain" an instance of this task on orientation
* change. The task can be "connected" to exactly one or zero objects
at any time. On orientation change, the old
* instance disconnects itself, then the new one connects. The object
you connect to typically is something that
* references back to your activity (might be the activity itself),
and which your task needs to do it's job (for
* example, where it posts it's results to). This class ensures that
whenever a new object connects while the task is
* still active, the preExecute() handler is run again, and if the
task finished while no object was connected, the
* processPostExecute() handler is run the next time an activity
connects. Note "processPostExecute()", which is a
* replacement for the "postExcute()" method of ASyncTask which you
should use instead. TODO: there is a small chance at
* race conditions here when checking for mWrapped and setting
mPostProcessingDone. We should fix those by using a lock.
*/
public abstract class ActivityAsyncTask<Wrapped, Params, Progress,
Result> extends AsyncTask<Params, Progress, Result>
{
protected Wrapped wrapped;
private boolean postProcessingDone;
private Result result;
public ActivityAsyncTask(Wrapped _wrapped)
{
super();
this.postProcessingDone = false;
connect(_wrapped);
}
/**
* Connect to the given object.
*/
public void connect(Wrapped _wrapped)
{
if ((this.wrapped != null) || (_wrapped == null))
throw new IllegalStateException();
this.wrapped = _wrapped;
// Set the task up with the new activity.
if (getStatus() == Status.RUNNING)
onPreExecute();
// If we were unable to do the full post processing because of
// no object being available, do so now.
else if ((getStatus() == Status.FINISHED) && !
this.postProcessingDone)
{
this.postProcessingDone = true;
processPostExecute(this.result);
this.result = null; // Be sure to free reference now.
}
}
/**
* Disconnect
*/
public void disconnect()
{
if (this.wrapped == null)
throw new IllegalStateException();
this.wrapped = null;
}
@Override
protected void onPostExecute(Result _result)
{
super.onPostExecute(_result);
// We need to make sure we only go on if an activity is
// attached. Since it's possible that, say, an orientation
// change happens while we are running, it can happen that
// there isn't one. If so, processPostExecute() will be
// run the next time one is attached.
if (this.wrapped != null)
{
this.postProcessingDone = true;
processPostExecute(_result);
}
else
// Remember result for the next connect.
this.result = _result;
}
/**
* You should override this rather than onPostExecute() to ensure
your handler will be called even if at the time of
* a finish the task is not connected.
*/
protected abstract void processPostExecute(Result _result);
}
--
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