【问题标题】:Can we persist a large state object through activity destruction?我们可以通过活动销毁来持久化一个大型状态对象吗?
【发布时间】:2021-01-19 19:48:59
【问题描述】:

问题:有时/在某些设备上,调用 startActivityForResult(活动 A)以启动活动 B 的活动在调用 startActivityForResult 之后和进入 onActivityResult 之前被销毁。我们在 onActivityResult 中获得了一个新创建的活动 A 实例以返回 - 这会导致我们的 ViewModel(以及所有其他成员变量)丢失。

然后,标准的做法是使用 SavedInstanceState 恢复 ui 状态。由于我们需要恢复的对象的大小,在这种情况下无法做到这一点 - 尝试这样做会导致 TransactionTooLargeException。 ViewModel 对于 Serializable 或 Parcelable 来说太大了。

问题:是否可以强制我们的 Activity 在此工作流程中保持完整?或者是否有其他设计可以让我们避免这个问题?不能将 ViewModel 的任何数据保存到磁盘。

上下文:这是一个项目,我们在其中存储从相机一次拍摄的图像列表(作为字节数组),以及在 ViewModel 中有关这些图像的一些相关信息。这些在 RecyclerView 中暂存,当用户完成添加图像时,它们可以在其中上传。我们通过调用 startActivityForResult 向这个 ViewModel 添加项目以启动相机活动并返回结果图像。

我们可能只看到由于打开开发者选项中的“不保留活动”设置而导致活动 A 被破坏的问题,这可能无法准确表示 Android 将如何回收资源(例如底部的对话这个线程的 - https://stackoverflow.com/questions/21227623/whats-the-main-advantage-and-disadvantage-of-do-not-keep-activities-in-android#:~:text=Android%20OS%20has%20this%20property,replicate%20the%20same%20scenario%20easily)。尽管如此,理想情况下,我们希望一切都可以使用此设置。现在,如果活动 A 被销毁,我们将丢失我们的成员变量和我们正在构建的 ViewModel,并且没有办法恢复它。

将 ViewModel 的数据存储在片段中(如在此处讨论:Fragment, save large list of data on onSaveInstanceState (how to prevent TransactionTooLargeException))将无法正常工作,因为我们的 Activity 正在被破坏,从而导致任何相关的片段也被破坏。我们实际上有一个以这种方式使用的片段,它从服务器加载并保存一个对象列表,以从中选择并与每个图像相关联——这个片段最终与活动一起被重新创建,当它被销毁然后执行时再次加载。

【问题讨论】:

    标签: android android-lifecycle


    【解决方案1】:

    不,你想要的是不可能的。如果您使用startActivityForResult() 启动另一个Activity 并且Activity 需要资源,则启动Activity 将被终止。您无法采取任何措施来防止这种情况发生。这是标准的 Android 行为,并且会发生,尤其是在低端设备上。

    如果您的ViewModel 太大而无法保存为实例状态,则需要将数据放在其他位置:SQLite 数据库或本地文件。然后将文件名或某个键作为保存的实例状态的一部分存储到数据库中,当Activity 重新启动时,从文件或数据库中恢复数据。

    注意:无论如何,您都不应该在内存中保留那么多数据,因为这会浪费宝贵的资源。仅将您真正需要的数据保留在内存中。

    【讨论】:

    • 感谢您的回答 - 这就是我的感觉。我们只是优雅地捕捉这个案例,并告诉用户在活动被破坏时一次上传一个项目。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-10
    • 1970-01-01
    • 2014-01-04
    • 1970-01-01
    • 2019-07-09
    相关资源
    最近更新 更多