Search code examples
androidkotlinandroid-intentandroid-activityonbackpressed

Android: How to close one activity on backpress and the entire backstack on another button press?


I have this scenario where I have a Main Activity and an Article Activity. The Main Activity opens an Article Activity, then if you click on a related article from the Article Activity, it opens the same activity again with the requested related article. So basically you can open 10 Article Activities on the top of each other and go back through every single one of them onBackPress() until you reach the Main Activity again. But the client also want a button that should send you directly back to the Main Activity without having to cycle through the entire BackStack again.

  • Basically we have MA -> AA -> AA -> AA -> (...).
  • On Back Press you should go back like MA <- AA <- AA <- AA sequentially through every new instance.
  • On Close All button press you should close all AA instances and go back straight to MA.

P.S. I don't want to lose the instance of MA. It should always be there in the backstack as the starting point.

How do I do this?


Solution

  • you can make a start function for your main activity and add required flags to Intent for clearing back stack and call that function in onClick of your button. also to avoid having multiple instances of MainActivity you should make its lunch mode singleInstance or singleTop in your manifest.for the start function you have multiple ways to implement.

    first way: define a static method in your MainActivity like this addFlags part is to clear the back stack when you call MainActivity if it's not necessary you can remove it

    companion object {
            @JvmStatic
            fun startActivity(context: Context) {
                val intent = Intent(context, KYCActivity::class.java).apply {
                    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or 
                         Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
                }
                context.startActivity(intent)
            }
        }
    

    and you can call it in your button click listener

    gotoHomeButton.setOnClickListener {
        MainActivity.startActivity(context)
    }
    

    second way: define a extention function for starting activities

    inline fun <reified T: Activity> Context.startActivity() {
        startActivity(Intent(this, T::class.java).apply {
            addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or 
                 Intent.FLAG_ACTIVITY_NEW_TASK)
        })
    }
    

    and then call the function like this

    gotoHomeButton.setOnClickListener {
        startActivity<MainActivity>()
    }
    

    it's not necessary to define these functions, you can just make a new instance of Intent in your buttons onClick but I like it this way.

    UPDATE FROM OP

    It apparently was as easy as adding (Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) flags to the AA activity on the Intent in button click. No need to add anything in manifest.