The way I deal with this in my apps is to override an Activity's onRetainCustomNonConfigurationInstance()
method, which allows you to retain an object through the restart that happens when the screen is rotated. Here's how I implement it.
I have an AsyncTask that performs a web request. The AsyncTask is in a separate file, and takes a reference to the calling Activity as a listener for some callbacks I have implemented. So the constructor for my web request AsyncTask is something like this:
private Callbacks listener;
public WebRequest(Callbacks listener) {
this.listener = listener;
}
I implement onRetainCustomNonConfigurationInstance()
in my Activity like this:
@Override
public Object onRetainCustomNonConfigurationInstance() {
if(webRequest != null) {
webRequest.detachFromActivity();
return webRequest;
} else {
return null;
}
}
Now, when my screen is rotated, the Activity restarts, and if my AsyncTask is running, it will save a reference to it here. Notice that I also "detach" my task from this current Activity, which will now be destroyed. I accomplish this in my task by just making the listener (which is the current Activity) null. Like this:
public void detachFromActivity() {
listener = null;
}
Now when the Activity restarts, in onCreate()
, I check to see if there was a retained reference to my running thread by calling getLastCustomNonConfigurationInstance()
like this:
Object retainedRequest = getLastCustomNonConfigurationInstance();
if(retainedRequest != null) {
if(retainedRequest instanceof WebRequest) {
webRequest = (WebRequest) retainedRequest;
webRequest.setListener(this);
}
}
Since the reference to my running thread is passed as an Object
, I need to retrieve it as an Object, then check if it's an instance of my AsyncTask, then cast it if it is.
The last step is to "reconnect" the callbacks to this NEW Activity, which was just created, so the task knows where to send the results. I use the setListener(this)
method to do it in my task, like this:
public void setListener(Callbacks listener) {
this.listener = listener;
}
Now I can re-attach a reference to an old thread with a newly re-created Activity. You may not be using an AsyncTask, but the concept is the same and should work for any Thread, or any object you want, really.
Hope this helps!