Ahora el caso complejo: Cuatro actividades y una de ellas muerta
Esta es la situación a la que me enfrentaba: La app tiene un flujo en el que algunas actividades se terminarían y otras se mantendrían mientras el usuario rellenaba los formularios.
El flujo problemático:
A started B
B started C; B finishes itself
C started D
D sends result to A
Así que la pila final sería
A -> B(killed) -> C -> D
¿Cómo enviar el resultado de D de vuelta a A?
Si no se mataba ninguna actividad, era cuestión de encadenar simplemente setResult() y onActivityResult(). Sin embargo, las cosas no son tan sencillas cuando se mata una actividad en medio del proceso.
Así que:
Actividad A
goToNextActivity(){
startActivityForResult(intentActivityB, SOME_REQUEST_CODE);
}onActivityForResult(...){
doSomeStuffWithResult();
}
Actividad B
goToNextActivity(){
intentActivityC = new Intent(...);
startActivity(intentActivityC);
}
Si sólo hacemos esto, habrá un problema: Como la actividad B ya no existe, el resultado que establecimos en la actividad C se perderá. Así que lo correcto es añadir esta bandera (FLAG_ACTIVITY_FORWARD_RESULT), con el fin de decirle a la intención de que esta actividad será terminada y eliminada de la pila, por lo tanto, el padre debe manejar el resultado.
NOTA 1: si su actividad padre será terminada también, puede utilizar esta bandera de nuevo para que la siguiente actividad en la pila maneje el resultado. Por esta razón, debe iniciar la actividad con startActivity en lugar de startActivityForResult (ya que no manejará ningún resultado como determina la bandera)
goToNextActivity(){
intentActivityC = new Intent(...);
intentActivityC.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
startActivity(intentActivityC);
}
Actividad C
goToNextActivity(){
intentActivityD = new Intent(…);
intentActivityD;
startActivityForResult(intentActivityD, SOME_REQUEST_CODE);
}onActivityResult(int reqCode, int resultCode){
if(reqCode == SOME_REQUEST_CODE){
setResult(resultCode);
finish();
}
}
Actividad D
goBackToActivityA(){
setResult(someResultCode);
finish();
}
Esto enviará someResultCode a C, que lo manejará con el onActivityResult y lo devolverá con setResult(…) finish();
que sabrá entonces por la bandera que la actividad B ya no existe, por lo que la actividad que debe manejarlo es la actividad A, lo que significa que el resultCode llegará finalmente al onActivityResultCode de la actividad A.