Nyt monimutkainen tapaus: Neljä aktiviteettia ja yksi niistä on tapettu
Tässä tilanteessa olin: Sovelluksessa on virtaus, jossa osa aktiviteeteista lopetettaisiin ja osa pidettäisiin, kun käyttäjä täyttää lomakkeita.
Ongelmallinen virtaus:
A started B
B started C; B finishes itself
C started D
D sends result to A
Loppupino olisi siis
A -> B(killed) -> C -> D
Miten lähetän tuloksen D:stä takaisin A:han?
Jos yksikään aktiviteetti ei olisi lopetettu, riittäisi pelkkä ketjuttaminen ketjuilla setResult() ja onActivityResult(). Asiat eivät kuitenkaan ole näin yksinkertaisia, kun aktiviteetti lopetetaan kesken prosessin.
Siten:
Aktiivisuus A
goToNextActivity(){
startActivityForResult(intentActivityB, SOME_REQUEST_CODE);
}onActivityForResult(...){
doSomeStuffWithResult();
}
Aktiivisuus B
goToNextActivity(){
intentActivityC = new Intent(...);
startActivity(intentActivityC);
}
Jos teemme vain näin, tulee ongelma: Koska aktiviteettia B ei enää ole olemassa, aktiviteetille C asettamamme tulos menetetään. Oikea tapa on siis lisätä tämä lippu (FLAG_ACTIVITY_FORWARD_RESULT) kertoaksemme intentille, että tämä aktiviteetti lopetetaan ja poistetaan backstackista, joten vanhemman pitäisi käsitellä tulos.
Huomautus 1: jos myös vanhemman aktiviteetti lopetetaan, voit käyttää tätä lippua uudestaan, jotta pinoissa seuraava aktiviteetti käsittelee tuloksen. Tästä syystä sinun on aloitettava aktiviteetti startActivityllä startActivityForResultin sijaan (koska se ei käsittele mitään tulosta, kuten lippu määrittää)
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();
}
Tämä lähettää someResultCode-koodin C:lle, joka käsittelee sen onActivityResultilla ja lähettää sen takaisin setResult(….) finish();
joka sitten tietää lipun perusteella, että aktiviteettia B ei enää ole olemassa, joten aktiviteetti, jonka pitäisi käsitellä sitä, on aktiviteetti A, mikä tarkoittaa, että resultCode saapuu lopulta aktiviteetin A onActivityResultCodeen.