崩溃/终止后的Android任务回栈和应用程序会话管理

崩溃/终止后的Android任务回栈和应用程序会话管理,android,session,crash,activity-lifecycle,back-stack,Android,Session,Crash,Activity Lifecycle,Back Stack,我想知道,在现代Android开发世界中,管理后台堆栈的常见做法或模式是什么,特别是当应用程序被杀死或崩溃时,系统试图重新创建其活动,因为应用程序创建的任务仍然存在 以下是在示例应用程序上演示上述行为的视频: 下面是源代码-基本上只是一个使用Android Studio向导创建的简单应用程序:ssh://git@github.com:lukaszs-appdate/crashingtask.git 假设应用程序在开始时显示登录活动。然后,当用户登录时,它会从服务器下载数据,并允许用户对数据进行操

我想知道,在现代Android开发世界中,管理后台堆栈的常见做法或模式是什么,特别是当应用程序被杀死或崩溃时,系统试图重新创建其活动,因为应用程序创建的任务仍然存在

以下是在示例应用程序上演示上述行为的视频:

下面是源代码-基本上只是一个使用Android Studio向导创建的简单应用程序:ssh://git@github.com:lukaszs-appdate/crashingtask.git

假设应用程序在开始时显示登录活动。然后,当用户登录时,它会从服务器下载数据,并允许用户对数据进行操作、启动其他活动、操纵应用程序的状态等。重要的假设是,当用户切换到不同的应用程序并返回到我们的应用程序时,他们会看到最后的活动,而不会返回登录。因此,我认为文档中的标志组合不足以解决问题

问题是,当: a) 应用程序崩溃并重新启动,或 b) 在Android中使用任务切换按钮将应用程序移动到后台,然后在Android Studio中手动关闭,并通过点击任务图标将其恢复, 然后Android尝试从任务中重新创建活动。我希望它只是从零开始在这些事件的情况下应用程序,并显示登录屏幕

我看到的唯一解决方案是针对所有活动的一些丑陋的父类,除了login一个,我们将检查是否设置了一些伪会话变量,如果没有,则假设应用程序已重新启动,并用login活动替换整个任务堆栈,或者对finish()调用进行一些链接,或者其他类似这样的事情

还有其他想法吗?当有问题的应用程序被杀死时,Android不能删除应用程序创建的任务吗


一个干净的解决方案是使用某种会话管理,允许任何活动有效地恢复应用程序的业务状态,使用户能够从任何活动中正确地恢复应用程序,即使它已被杀死。但这是另一个讨论。

我在Kotlin中编写了这段代码,它可以帮助我识别再次出现的活动。 我意识到返回的活动不会调用onCreate(Bundle)(afaik)。因此,如果您有一个
BaseActivity
,您可以这样做

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
    }

}
注意


如果您从
服务启动活动(例如推送通知)。您必须设置
startedWithLauncher=true
,否则看起来应用程序没有启动启动器活动

你解决了这个问题吗?