5

I was wondering what are common practices or patterns in modern Android development world regarding management of the Back Stack, in particular handling cases when app is killed, or crashes, and system tries to recreate its activities because the task that the app created still exists.

Here's the vid that demonstrates behavior described above on a sample app: https://www.dropbox.com/s/pkm88dvdpzsw9lm/IMG_2334-480.mov?dl=0

And here's the source code - basically just a simple app created using Android Studio wizard: ssh://git@github.com:lukaszs-appdate/crashingtask.git

Let's say the app shows a login activity at the start. Then when user logs in it downloads data from server and allows the user to operate on the data, start other activities, manipulate the state of the app, etc. Important assumption is that when user e.g. switches to different app and goes back to our app, they see the last Activity and not going back to login. So I don't think the flags combinations from the doc https://developer.android.com/guide/components/activities/tasks-and-back-stack.html would be sufficient to solve the problem.

And the problem is, that when: a) the app crashes and is restarted, or b) the app is moved to background using task switching button in Android, then killed manually in Android Studio and brought back by tapping the task icon, then Android tries to recreate the activities from the task. I want it to just start the app from scratch in case of these events and show the login screen.

The only solution I see is some ugly parent class for all activities except the login one, where we would check if some pseudo-session-variable is set, and if it's not, assume that the app was restarted and replace the whole task stack with login activity, or do some chaining of finish() invocations, or other smelly stuff like this.

Any other ideas? Can't Android just delete the task created by the app when the app in question is killed?

A clean solution for this would be to use some kind of session management, allowing any activity to restore the app's business state effectively enabling the user to bring back the app correctly from any activity, even when it was killed. But that's for another discussion.

Łukasz Sromek
  • 3,637
  • 3
  • 30
  • 43

1 Answers1

0

I wrote this code in Kotlin that helps me to identify this activity coming back. I've realised that the Activity coming back doesn't call onCreate(Bundle) (afaik). So if you have a BaseActivity, you could do it that way.

class BaseActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        startedWithLauncher = startedWithLauncher || intent.action == Intent.ACTION_MAIN
        super.onCreate(savedInstanceState)
    }

    override fun onResume() {
        super.onResume()
        if (!didStartWithLauncher()) {
            // Do something
        }
    }

    fun didStartWithLauncher(): Boolean {
        return startedWithLauncher;
    }

    companion object {
        /**
         * Situation:
         * You have a Stack with Activity (A - Main Launcher, B, C). C crashes, when you click in "Open app again",
         * I don't know why but it opens the Activity B, recreating the stack, but this might not be
         * what you want.
         * We're setting this variable to ask if it started from the launcher.
         * We need to write this variable before super.onCreate(savedInstanceState).
         */
        private var startedWithLauncher = false
    }

}

ATTENTION!

If you start an Activity from a Service (push notifications, for example). You have to set that startedWithLauncher = true, otherwise it will look like the app didn't start with the Launcher Activity!

Rafael Ruiz Muñoz
  • 5,333
  • 6
  • 46
  • 92