k-9/src/com/fsck/k9/activity/misc/ExtendedAsyncTask.java

112 lines
3.2 KiB
Java

package com.fsck.k9.activity.misc;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
/**
* Extends {@link AsyncTask} with methods to attach and detach an {@link Activity}.
*
* <p>
* This is necessary to properly handle configuration changes that will restart an activity.
* </p><p>
* <strong>Note:</strong>
* Implementing classes need to make sure they have no reference to the {@code Activity} instance
* that created the instance of that class. So if it's implemented as inner class, it needs to be
* {@code static}.
* </p>
*
* @param <Params>
* see {@link AsyncTask}
* @param <Progress>
* see {@link AsyncTask}
* @param <Result>
* see {@link AsyncTask}
*
* @see #restore(Activity)
* @see #retain()
*/
public abstract class ExtendedAsyncTask<Params, Progress, Result>
extends AsyncTask<Params, Progress, Result> implements NonConfigurationInstance {
protected Activity mActivity;
protected Context mContext;
protected ProgressDialog mProgressDialog;
protected ExtendedAsyncTask(Activity activity) {
mActivity = activity;
mContext = activity.getApplicationContext();
}
/**
* Connect this {@link AsyncTask} to a new {@link Activity} instance after the activity
* was restarted due to a configuration change.
*
* <p>
* This also creates a new progress dialog that is bound to the new activity.
* </p>
*
* @param activity
* The new {@code Activity} instance. Never {@code null}.
*/
@Override
public void restore(Activity activity) {
mActivity = activity;
showProgressDialog();
}
/**
* Detach this {@link AsyncTask} from the {@link Activity} it was bound to.
*
* <p>
* This needs to be called when the current activity is being destroyed during an activity
* restart due to a configuration change.<br/>
* We also have to destroy the progress dialog because it's bound to the activity that's
* being destroyed.
* </p>
*
* @return {@code true} if this instance should be retained; {@code false} otherwise.
*
* @see Activity#onRetainNonConfigurationInstance()
*/
@Override
public boolean retain() {
boolean retain = false;
if (mProgressDialog != null) {
removeProgressDialog();
retain = true;
}
mActivity = null;
return retain;
}
/**
* Creates a {@link ProgressDialog} that is shown while the background thread is running.
*
* <p>
* This needs to store a {@code ProgressDialog} instance in {@link #mProgressDialog} or
* override {@link #removeProgressDialog()}.
* </p>
*/
protected abstract void showProgressDialog();
protected void removeProgressDialog() {
mProgressDialog.dismiss();
mProgressDialog = null;
}
/**
* This default implementation only creates a progress dialog.
*
* <p>
* <strong>Important:</strong>
* Be sure to call {@link #removeProgressDialog()} in {@link AsyncTask#onPostExecute(Object)}.
* </p>
*/
@Override
protected void onPreExecute() {
showProgressDialog();
}
}