Nu het complexe geval: Vier activiteiten en een van hen gedood
Hier is de situatie waarmee ik werd geconfronteerd: De app heeft een flow dat sommige activiteiten zouden worden beëindigd en sommige zouden worden bewaard terwijl de gebruiker de formulieren invulde.
De problematische flow:
A started B
B started C; B finishes itself
C started D
D sends result to A
Dus de uiteindelijke stack zou zijn
A -> B(killed) -> C -> D
Hoe stuur je het resultaat van D terug naar A?
Als er geen activiteit werd gedood, was het een kwestie van gewoon chainen setResult() en onActivityResult(). De zaken liggen echter niet zo eenvoudig als je een activiteit midden in het proces doodt.
Dus:
Activiteit A
goToNextActivity(){
startActivityForResult(intentActivityB, SOME_REQUEST_CODE);
}onActivityForResult(...){
doSomeStuffWithResult();
}
Activiteit B
goToNextActivity(){
intentActivityC = new Intent(...);
startActivity(intentActivityC);
}
Als we alleen dit doen, ontstaat er een probleem: omdat activiteit B niet meer bestaat, gaat het resultaat dat we op activiteit C hebben ingesteld, verloren. Dus het juiste is om deze vlag toe te voegen (FLAG_ACTIVITY_FORWARD_RESULT), om de intent te vertellen dat deze activiteit zal worden beëindigd en verwijderd uit de backstack, vandaar dat de ouder het resultaat moet verwerken.
NOTE 1: als je ouderactiviteit ook zal worden beëindigd, kun je deze vlag opnieuw gebruiken, zodat de volgende activiteit in de stack het resultaat zal verwerken. Om deze reden moet je de activiteit starten met startActivity in plaats van startActivityForResult (omdat deze geen resultaat zal afhandelen zoals de vlag bepaalt)
goToNextActivity(){
intentActivityC = new Intent(...);
intentActivityC.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
startActivity(intentActivityC);
}
Activiteit C
goToNextActivity(){
intentActivityD = new Intent(…);
intentActivityD;
startActivityForResult(intentActivityD, SOME_REQUEST_CODE);
}onActivityResult(int reqCode, int resultCode){
if(reqCode == SOME_REQUEST_CODE){
setResult(resultCode);
finish();
}
}
Activiteit D
goBackToActivityA(){
setResult(someResultCode);
finish();
}
Dit zal someResultCode naar C sturen, die het zal afhandelen met de onActivityResult en het weer terug zal sturen met setResult(…) finish();
die dan door de vlag weet dat de activiteit B niet meer bestaat, dus de activiteit die het moet afhandelen is activiteit A, wat betekent dat de resultCode uiteindelijk in de onActivityResultCode van activiteit A aankomt.