O contexto do Android AsyncTask terminou
-
25-09-2019 - |
Pergunta
Quando uma atividade termina, por exemplo, após a mudança da orientação da tela, é possível alterar um AsyncTask
contexto de atividade? Caso contrário, criará um erro porque quando a atividade termina AsyncTask
O contexto de atividade de So foi desaparecido também.
Meu dever de casa feito é o seguinte:
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
Solução
O que você passa no seu onRetainNonConfigurationInstance()
? O que eu faço é passar um objeto para ele contendo o AsyncTask
, e então eu tento recuperar o valor em getLastNonConfigurationInstance()
.
EDIT: Pensando segundo, isso dependeria do que você deseja fazer após uma mudança de configuração. Se você quiser encerrar o AsyncTask
, e então ligue cancel()
nele. Se você deseja continuar seu processamento mesmo após uma mudança de orientação, precisará manter a tarefa.
Você pode fazer isso salvando o Activity
no AsyncTask
assim:
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;
}
}
Outras dicas
no método oncâncel da sua tarefa de assíncrona, PUST FINAL ();
public void onCancel(DialogInterface dialog) {
cancel(true);
dialog.dismiss();
finish();
}