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 android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to