崩溃/终止后的 Android 任务返回堆栈和应用程序 session 管理

标签 android session crash activity-lifecycle back-stack

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

这是演示上述示例应用程序行为的视频:https://www.dropbox.com/s/pkm88dvdpzsw9lm/IMG_2334-480.mov?dl=0

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

假设应用在开始时显示登录 Activity 。然后,当用户登录时,它会从服务器下载数据,并允许用户对数据进行操作、启动其他 Activity 、操纵应用程序的状态等。重要的假设是,当用户例如切换到不同的应用程序并返回到我们的应用程序,他们会看到最后一个 Activity 并且不会返回登录。所以我不认为文档中的标志组合 https://developer.android.com/guide/components/activities/tasks-and-back-stack.html足以解决问题。

问题是,当: a) 应用程序崩溃并重新启动,或者 b) 使用 Android 中的任务切换按钮将应用移至后台,然后在 Android Studio 中手动终止并通过点击任务图标恢复, 然后 Android 尝试从任务中重新创建 Activity 。我希望它在发生这些事件时从头开始启动应用程序并显示登录屏幕。

我看到的唯一解决方案是为除登录 Activity 之外的所有 Activity 设置一些丑陋的父类,我们将在其中检查是否设置了一些伪 session 变量,如果没有设置,则假设应用程序已重新启动并替换整个带有登录 Activity 的任务堆栈,或者做一些 finish() 调用的链接,或者其他像这样的臭东西。

还有其他想法吗? Android 不能在有问题的应用程序被终止时删除应用程序创建的任务吗?

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

最佳答案

我用 Kotlin 编写了这段代码,它帮助我识别返回的 Activity 。 我已经意识到返回的 Activity 不会调用 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
    }

}

注意!

如果您从 Service 启动一个 Activity(例如推送通知)。您必须设置 startedWithLauncher = true,否则它看起来就像应用程序没有启动 Launcher Activity!

关于崩溃/终止后的 Android 任务返回堆栈和应用程序 session 管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43047435/

相关文章:

java - 一个接一个地播放音乐

android - Android 设备上的 SQLite 数据库与 SQL Server 数据库之间的同步

php - 如果 session 不存在则重定向

ios - 'NSInternalInconsistencyException',原因 : 'containerView is required.'

java - 在本地主机上抛出套接字异常,但不在网络上抛出?

android - setLogo toolbar from url 图片

ruby-on-rails - Rails 3 跨子域 flash 消息

IIS Web Farm 上的 session Cookie

javascript - 如何避免从查询中读取行时超时(Phonegap + Javascript)

java - 当主题从深色更改为浅色时重新加载 Activity ,反之亦然