import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; public abstract class DetachableTask extends AsyncTask { protected Activity owner; protected Context ctx; private ProgressDialog dialog; private String dialogMessage = ""; private String dialogTitle = ""; // An Activity's onCreate should use this if it might have previously // owned some retained task, e.g. // myTask = DetachableTask.doRestore(getLastNonConfigurationInstance(), this)) @SuppressWarnings("unchecked") public static DetachableTask doRestore(Object task, Activity owner) { // We can't check that the desired parameter is correct, but we can // at least make sure it's some kind of DetachableTask. DetachableTask checkTask = (DetachableTask)task; DetachableTask aTask = (DetachableTask)checkTask; if (aTask != null) aTask.attach(owner); return aTask; } // An Activity's onRetainNonInstanceState should use this if it might own // some task, e.g.: // return DetachableTask.doRetain(myTask, this); public static Object doRetain(DetachableTask task, Activity maybeOwner) { if (task != null && maybeOwner == task.owner) task.detach(); return task; } // An Activity's onDestroy should use this if it might own some task, e.g.: // return DetachableTask.doDestroy(myTask, this); public static boolean doDestroy(DetachableTask task, Activity maybeOwner, boolean mayInterrupt) { if (task != null) return task.cancelIfOwned(maybeOwner, mayInterrupt); return false; } protected DetachableTask(Activity owner, String titleId, String msgId) { ctx = owner.getApplicationContext(); dialogTitle = titleId; setDialogMessage(msgId); attach(owner); } protected DetachableTask(Activity owner, int titleId, int msgId) { this(owner, owner.getString(titleId), owner.getString(msgId)); } protected void setDialogMessage(int id) { setDialogMessage(ctx.getString(id)); } protected void setDialogMessage(String msg) { dialogMessage = msg; if (dialog != null) dialog.setMessage(msg); } public void detach() { attach(null); } public boolean isAttached() { return owner != null; } public boolean cancelIfOwned(Activity maybeOwner, boolean mayInterrupt) { if (maybeOwner == owner) return cancel(mayInterrupt); return false; } public static boolean isActive(AsyncTask task) { return task != null && task.getStatus() != AsyncTask.Status.FINISHED; } protected void cancelDialog() { if (dialog != null) dialog.cancel(); dialog = null; } protected void publishProgress(int msgId) { publishProgress(ctx.getString(msgId)); } public void attach(Activity owner) { if (owner != this.owner) cancelDialog(); this.owner = owner; if (isAttached() && getStatus() != AsyncTask.Status.FINISHED && dialog == null) dialog = ProgressDialog.show(owner, dialogTitle, dialogMessage, true, false); } @Override protected void onProgressUpdate(String... message) { setDialogMessage(message[0]); } @Override protected void onPostExecute(String finalMessage) { cancelDialog(); } }