I did have similar problems with asynctask in an activity : the activity is destroyed on screen rotation and recreated thus recreating the asynctask.
To solve this :
easy but not elegant : prevent activity from being destroyed with android:configChanges="orientation" in your manifest for your activity.
a bit complex : create a class that stores the current activity controls, save it in onRetainNonConfigurationInstance and restore it in onCreate. When the asynctask is started, instead of talking to the activity directly, it talks to this class that persists through rotation. I can provide some code if you want (it's a bit long).
Edit : Here's some code.
package com.ybi;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;
public class EmptyShellActivity extends Activity {
private ActivityControl activityControl;
private EmptyShellTask emptyShellTask;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView)findViewById(R.id.textView1);
restoreFromObject();
}
@Override
public Object onRetainNonConfigurationInstance() {
activityControl.textView = null;
return activityControl;
}
private void restoreFromObject() {
activityControl = (ActivityControl) getLastNonConfigurationInstance();
if (activityControl == null) {
activityControl = new ActivityControl();
activityControl.textView = textView;
activityControl.textView.setText("Doing");
emptyShellTask = new EmptyShellTask();
emptyShellTask.execute((Void[])null);
} else {
activityControl.textView = textView;
if (activityControl.isInProgress)
activityControl.textView.setText("Doing");
else
activityControl.textView.setText("Done");
}
}
protected class ActivityControl {
protected boolean isInProgress;
protected TextView textView;
}
private class EmptyShellTask extends
AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
activityControl.isInProgress = true;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// say something
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
activityControl.isInProgress = false;
activityControl.textView.setText("Done");
}
}
}
I just removed some things from one of my class. I usually use an interface instead of writing code in postExecute. It helps to prevent having pieces of code that do UI things everywhere (like repeating the Done Doing display).
If you want to go further (like progress control, cancel tasks, error management), I ve got interesting piece of code. The only problem is that it becomes rapidly very very complex.