Question

When an Activity terminates, e.g. after screen orientation changing, is that possible to change an AsyncTask activity context? Else it will create an error because when the activity terminates AsyncTask's activity context is gone too.

My homework done is the following:

public void onSaveInstanceState(Bundle savedInstanceState) <- doesn't solve
public Object onRetainNonConfigurationInstance()  <- doesn't solve
android:configChanges="keyboardHidden|orientation" 
                     <- solved but doesn't handle well relative layouts
Was it helpful?

Solution

What do you pass on your onRetainNonConfigurationInstance()? What I do is pass an object to it containing the AsyncTask, and then I try to retrieve the value in getLastNonConfigurationInstance().

EDIT: On second thought, it would depend on what you want to do after a configuration change. If you want to terminate the AsyncTask, and then call cancel() on it. If you want to continue its processing even after an orientation change, then you have to hold on to the task.

You can do that by saving the Activity in the AsyncTask like this:

private MyAsyncTask searchTask;

@Override
public void onCreate(Bundle savedInstance){
 super.onCreate(savedInstance);

 if (getLastNonConfigurationInstance()!=null) {
  SavedObject savedObj = (SavedObject)getLastNonConfigurationInstance();

  searchTask = savedObj.getAsyncTask();
  searchTask.attach(this);
 } else {
  searchTask = new MyAsyncTask(this);
  searchTask.execute();
 }
}

@Override
public Object onRetainNonConfigurationInstance(){

 searchTask.detach();

 final SavedObject savedObj = new SavedObject();
 savedObj.setAsyncTask(searchTask);

    return savedObj;
}


private class MyAsyncTask extends AsyncTask<Void, Void, Void> {

 MyActivity parentActivity = null;

    MyAsyncTask (MyActivity activity) {
  attach(activity);   
 }

 void attach(MyActivity activity) {
  this.parentActivity=activity;
 }

 void detach() {
  parentActivity=null;
 }

 // Do your thread processing here
}


private class SavedObject {
 private MyAsyncTask asyncTask;

 public void setAsyncTask(MyAsyncTask asyncTask){
  this.asyncTask = asyncTask;
 }

 public MyAsyncTask getAsyncTask() {
  return asyncTask;
 }
}

OTHER TIPS

in the OnCancel method of your asynch task put finish();

        public void onCancel(DialogInterface dialog) {
        cancel(true);
        dialog.dismiss();
        finish();
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top