Teraz skomplikowany przypadek: Cztery aktywności i jedna z nich zabita
Oto sytuacja, z którą miałem do czynienia: Aplikacja ma przepływ, w którym niektóre działania zostałyby zakończone, a niektóre zostałyby zachowane w miarę wypełniania formularzy przez użytkownika.
Problemowy przepływ:
A started B
B started C; B finishes itself
C started D
D sends result to A
Więc ostateczny stos byłby
A -> B(killed) -> C -> D
Jak wysłać wynik z D z powrotem do A?
Jeśli żadna aktywność nie została zabita, była to kwestia tylko łańcuchowania setResult() i onActivityResult(). Jednak sprawy nie są takie proste, gdy zabijasz aktywność w środku procesu.
Więc:
Aktywność A
goToNextActivity(){
startActivityForResult(intentActivityB, SOME_REQUEST_CODE);
}onActivityForResult(...){
doSomeStuffWithResult();
}
Aktywność B
goToNextActivity(){
intentActivityC = new Intent(...);
startActivity(intentActivityC);
}
Jeśli tylko to zrobimy, pojawi się problem: Ponieważ aktywność B już nie istnieje, wynik, który ustawiliśmy na aktywności C zostanie utracony. Więc właściwą rzeczą do zrobienia jest dodanie tej flagi (FLAG_ACTIVITY_FORWARD_RESULT), aby powiedzieć intencji, że ta aktywność zostanie zakończona i usunięta ze stosu, dlatego rodzic powinien obsłużyć wynik.
UWAGA 1: jeśli twoja aktywność nadrzędna również zostanie zakończona, możesz użyć tej flagi ponownie, aby następna aktywność w stosie obsłużyła wynik. Z tego powodu musisz rozpocząć aktywność za pomocą startActivity zamiast startActivityForResult (ponieważ nie będzie ona obsługiwać żadnego wyniku, jak określa flaga)
goToNextActivity(){
intentActivityC = new Intent(...);
intentActivityC.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
startActivity(intentActivityC);
}
Activity C
goToNextActivity(){
intentActivityD = new Intent(…);
intentActivityD;
startActivityForResult(intentActivityD, SOME_REQUEST_CODE);
}onActivityResult(int reqCode, int resultCode){
if(reqCode == SOME_REQUEST_CODE){
setResult(resultCode);
finish();
}
}
Activity D
goBackToActivityA(){
setResult(someResultCode);
finish();
}
To wyśle someResultCode do C, który obsłuży go za pomocą onActivityResult i odeśle go z powrotem za pomocą setResult(….) finish();
które będzie wtedy wiedziało po fladze, że aktywność B już nie istnieje, stąd aktywnością, która powinna ją obsłużyć jest aktywność A, co oznacza, że resultCode w końcu dotrze do onActivityResultCode aktywności A.