android - 如果 Android 重新启动我的应用程序,我如何确保它不会加载最新的片段?
问题描述
我的应用程序包含两个活动:SignInActivity 和 MainActivity。SignInActivity 允许用户登录,并初始化应用程序正常运行所需的一系列重要变量。MainActivity 包含一堆组成实际应用程序的片段。这些片段使用带有ViewModel
s 的 MVVM 架构。这些Fragment
类从它们的 ViewModel 加载信息以显示在屏幕上。
一Fragment
,AppleFragment,通过调用加载苹果的类型(用户之前输入的)vm.getAppleType().getName()
。AppleFragment 然后在屏幕上显示苹果的类型。用户只有在设置了苹果的类型后才能导航到 AppleFragment。
假设用户在 MainActivity 和 AppleFragment 中使用我的应用程序时按下了主页按钮。该应用程序将被移至后台,并可能被 Android 操作系统杀死以节省内存。如果是这种情况,然后用户转到概览屏幕(即方形按钮),并选择要打开的应用程序,Android 将重新启动上次打开的 Activity (MainActivity),以及上次打开的片段(AppleFragment),但所有变量(包括 ViewModel 中的变量)都是新鲜的——即从头开始。
由于 AppleFragmentvm.getAppleType().getName()
在 onViewCreated() 中加载,并且 ViewModel 完全空白 - 请记住 Android 销毁所有内容以节省内存 -vm.getAppleType().getName()
导致 NPE 和应用程序崩溃。
为了缓解这种情况,我让 MainActivity 检查重要的应用程序变量是否已初始化,如果没有,则启动 SignInActivity。这个想法是在上面详述的情况下,用户将被重定向到 SignInActivity,并且应用程序将在用户登录时填充重要变量。用户将无法导航到 AppleFragment,直到他们设置了苹果类型然后 ViewModel 可以交给 AppleFragment 来显示。
这种方法并不完全奏效,因为 startActivity() 会安排 SignInActivity,但不会立即启动它——尤其是在 MainActivity 的所有生命周期方法完成运行之前。似乎作为 MainActivity 的 onStart() 方法的一部分,最后查看的片段 AppleFragment 已加载。这就是我们遇到麻烦的地方,因为 AppleFragmentvm.getAppleType().getName()
在其 onViewCreated 方法中调用会导致 NPE 和应用程序崩溃。
解决方案
从文档:
如果您不需要存储大量数据并且不需要结构,则应该使用 SharedPreferences。SharedPreferences API 允许您读取和写入原始数据类型的持久键值对:布尔值、浮点数、整数、长整数和字符串。
我认为这应该有助于解决您的问题。
我认为当变量丢失时重定向用户再次登录是不行的。我建议将这些值保存在 SharedPrefences 中。如果您担心安全性,可以阅读:Android SharedPreference security
推荐阅读
- ubuntu-18.04 - 当服务器上的特定二进制文件更新时,systemd 可以重新启动服务吗?
- sql - 如何在 SQL Server 中循环遍历数据并将上一个批次与当前批次进行比较?
- firebase - 每次将数据写入我的 Google Cloud Firestore 存储桶时,是否有办法获取电子邮件或文本通知?
- arrays - Mongo在文档中查找和修改数组
- javascript - Nativescript 无法获取 TextField 值 在任何地方都没有找到解决方案
- javascript - 如何在没有 id 的元素中使用 querySelectorAll?
- reactjs - 材料 ui 图标的 React + Typescript 错误
- c++ - 在 C++ 中迭代地从标准输入读取字节
- python - 在外键上过滤查询集
- r - 替换匹配多个不同模式的列值