He estado trabajando con AsyncTasks en Android y estoy lidiando con un problema.Comportamiento de contexto Android AsyncTask
Tome un ejemplo simple, una Actividad con una AsyncTask. La tarea en el fondo no hace nada espectacular, simplemente duerme durante 8 segundos.
Al final de AsyncTask en el método onPostExecute() solo estoy configurando el estado de visibilidad de un botón en View.VISIBLE, solo para verificar mis resultados.
Ahora, esto funciona de maravilla hasta que el usuario decida cambiar la orientación de su teléfono mientras está funcionando la AsyncTask (dentro de la ventana de espera de 8 segundos).
Entiendo el ciclo de vida de la actividad de Android y sé que la actividad se destruye y vuelve a crear.
Aquí es donde aparece el problema. AsyncTask se refiere a un botón y aparentemente contiene una referencia al contexto que inició la AsyncTask en primer lugar.
Supongo que este contexto anterior (ya que el usuario provocó un cambio de orientación) se convertirá en nulo y AsyncTask arrojará un NPE para la referencia al botón que intenta hacer visible.
En su lugar, no se lanza NPE, la AsyncTask cree que la referencia del botón no es nula, lo establece en visible. ¿El resultado? ¡No pasa nada en la pantalla!
Actualización: He abordado esto manteniendo un WeakReference
en la actividad y el cambio cuando ocurre un cambio de configuración. Esto es engorroso.
Aquí está el código:
public class Main extends Activity {
private Button mButton = null;
private Button mTestButton = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mButton = (Button) findViewById(R.id.btnStart);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
new taskDoSomething().execute(0l);
}
});
mTestButton = (Button) findViewById(R.id.btnTest);
}
private class TaskDoSomething extends AsyncTask<Long, Integer, Integer>
{
@Override
protected Integer doInBackground(Long... params) {
Log.i("LOGGER", "Starting...");
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 0;
}
@Override
protected void onPostExecute(Integer result) {
Log.i("LOGGER", "...Done");
mTestButton.setVisibility(View.VISIBLE);
}
}
}
intente ejecutar y mientras que el AsyncTask está trabajando cambiar su orientación móviles.
es un poco engañoso escribir "mantener una WeakReference a la actividad" y no hacerlo en el código. Peor aún, más adelante dice "y cambiar cuando ocurre un cambio de configuración", lo que significa realmente nada ... ¿Cambiar qué? – Ewoks