Start a new task with an activity already in the backstack

from the CommonsWare Community archives

At November 28, 2019, 10:04am, Raptor asked:

Hello,

I am implementing an onboarding process in an app that has an activity and several fragments (and potential later activities). I get to this activity, let’s call it “SummaryActivity” from my MainActivity. Once I’m in the SummaryActivity, in start my process of entering a phone number, receiving an OTP and all the registration jazz. However, if the user is already registered, I display an AlertDialog saying that the user is registered, and when pressing the OK button I want to restart the entire process.

How is the optimal way to approach this such that I get to my SummaryActivity again, at the beginning, and yet allow the user to press “back” and get to the MainActivity. How do I start a task where there already is an activity (in this case, MainActivity) in the back stack, while the task starts in SummaryActivity? I remember doing this in the past but not sure how.

Thanks!


At November 28, 2019, 1:49pm, mmurphy replied:

I doubt that starting a task here is the solution. Beyond that, though, I do not know what your activity back stack is at the time that you want to make a change.

My interpretation is that you want the activity back stack in the end to look like:

MainActivity <- SummaryActivity

(i.e., pressing BACK from SummaryActivity returns you to MainActivity)

However, that feels like that is also your starting point, as it feels like SummaryActivity is the one that is showing your dialog. If so, then it seems like “at the beginning” would be a matter of telling your viewmodel to reset itself (or the equivalent in your chosen architecture).

If your question is “how do I start an activity and add another activity behind it on the back stack?”, use startActivities() instead of startActivity().


At November 28, 2019, 3:05pm, Raptor replied:

Yes, your assumptions are correct.

What I ended up doing in the end is this:

(BaseActivity that SummaryActivity extends):

fun restartOnBoarding() {
    val intent = Intent(this, MainActivity::class.java)
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
    intent.putExtra(FROM_ONBOARDING, true)
    startActivity(intent)
}

And then in my MainActivity:

 override fun onStart() {
    super.onStart()
    val fromOnboarding: Boolean? = intent?.extras?.getBoolean(FROM_ONBOARDING)
    fromOnboarding?.let {
        if (it) goToOnboarding()
        intent.removeExtra(FROM_ONBOARDING)
    }
}

So, whenever I need to “reset the process”, I actually go to MainActivity and immediately launch SummaryActivity. This doesn’t look too bad in my tests and, to be honest, it looks kinda ugly, but it works. Unless you can think of a better way.


At November 28, 2019, 3:36pm, mmurphy replied:

If MainActivity in your scenario is not doing anything other than start SummaryActivity, you could try startActivities() instead of startActivity(). Your Intent array would contain MainActivity and SummaryActivity, so startActivities() would show SummaryActivity but a BACK press would “return” the user to MainActivity.