移动应用中的状态恢复:是什么、机制及工作原理

作者: IT Sectr 发布日期: 2026-05-18 阅读时间: 8 分钟

状态恢复(State Restoration)是移动操作系统的一种机制,允许在应用重启或最小化后保存和恢复用户界面。系统将UI状态保存在内存或持久存储中,并在重新打开时恢复。根据Android Developers(2025)的数据,State Restoration对于追求高质量用户体验的应用是必需的。State Restoration对于防止应用意外关闭时的数据丢失至关重要。

要点

  • State Restoration — 在应用重启时保存和恢复UI的机制,防止用户数据和上下文的丢失。
  • 生命周期 — 在最小化、设备重启或系统关闭应用后的重启时激活恢复。
  • 平台 — iOS通过UIKit(NSUserActivity、UIStateRestoring)支持State Restoration,Android通过SavedStateHandle和ViewModel支持。
  • 要保存的数据 — 滚动位置、表单中输入的数据、导航状态、多媒体内容和选定元素。
  • 实现 — 需要将状态序列化为Bundle或NSData,并在相应的生命周期方法中恢复。

什么是State Restoration?

State Restoration(状态恢复)是一种系统机制,允许保存应用的当前用户界面状态,并在关闭或重启后恢复它。当用户最小化应用或系统为释放资源而关闭应用时,State Restoration会记录UI的关键参数并将其保存在加密存储中。

如果没有State Restoration,用户在应用间切换时会丢失所有未保存的数据。例如,已填写的联系表单、较长的搜索查询或部分浏览的新闻列表——所有这些在重启时都会消失。State Restoration通过在最小化时刻自动记录ViewController或Activity的状态来解决这个问题。

该机制在系统级别工作,并受到两个主要移动平台的支持。iOS通过NSUserActivity和UIStateRestoring协议提供State Restoration,而Android通过Jetpack架构组件中的SavedStateHandle和ViewModel提供。实现方式不同,但概念相同。

State Restoration机制如何工作?

State Restoration过程分为两个阶段:保存(save)和恢复(restore)。在保存阶段,系统调用相应的生命周期方法,应用必须将当前UI状态序列化为紧凑表示。在恢复阶段,系统将保存的数据返回,应用将其反序列化以恢复UI。

状态保存机制

保存由系统在应用进入后台模式或收到即将关闭的信号时启动。在iOS中,调用UIViewController中的encodeRestorableState方法,在Android中调用Activity中的onSaveInstanceState或通过SavedStateHandle保存。数据被序列化为支持原始类型的格式:字符串、数字、字节数组和Parcelable对象。

保存的数据量应尽可能小——系统对保存包的大小施加限制。在Android中,每个进程的限制约为50 KB。超出限制会导致TransactionTooLargeException异常。因此,架构师建议只保存标识符和键,而在恢复时从持久存储中加载完整数据。

从保存状态恢复UI

恢复时,系统在启动时将保存的数据包传递给应用。在iOS中,调用decodeRestorableState方法,在Android中调用onRestoreInstanceState或从SavedStateHandle读取。应用从数据包中提取标识符和键,并恢复UI:滚动位置、选定元素、输入的数据。

重要的是要考虑恢复可能在新进程中发生。如果应用已从内存中完全卸载,进程会重新创建,内存中的所有对象都不存在。因此,状态必须是可序列化的,并且独立于先前会话的运行时上下文。这对于具有多个输入字段的大表单和长多页界面尤其关键。

kotlin
class MainActivity : AppCompatActivity() {
    private var searchQuery: String = ""

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putString("search_query", searchQuery)
    }

    override fun onRestoreInstanceState(savedState: Bundle) {
        super.onRestoreInstanceState(savedState)
        searchQuery = savedState.getString("search_query", "")!!
        restoreSearchUI(searchQuery)
    }
}

iOS和Android上的State Restoration

State Restoration的实现因平台而异。iOS通过storyboard和UIKit协议使用声明式方法,而Android通过Activity生命周期方法和Jetpack架构组件使用命令式方法。方法的选择取决于目标平台和应用架构。

iOS中的State Restoration(UIKit)

在iOS中,State Restoration建立在三个组件之上:UIApplication管理整个过程,UIViewController实现UIStateRestoring协议,NSUserActivity存储用于恢复导航的数据。要启用,需要在UIViewController中设置restorationIdentifier并实现encodeRestorableState和decodeRestorableState。

iOS会自动保存导航控制器(UINavigationController)和所有嵌套的ViewController的状态,如果它们设置了restorationIdentifier。系统管理导航堆栈并将其恢复到原始状态。然而,控制器内部的数据(输入的文本、滚动位置)必须由开发人员显式保存。

Android中的State Restoration(SavedStateHandle)

在Android中,现代的State Restoration方法基于SavedStateHandle——一个来自AndroidX Lifecycle库的组件。SavedStateHandle在ViewModel内部可用,并在配置更改(屏幕旋转)和进程重启时自动保存和恢复数据。数据存储在Bundle中并自动序列化。

SavedStateHandle的行为类似于键值存储,支持LiveData。在配置更改时,数据会自动保存和恢复。为了支持进程重启,ViewModel必须通过SavedStateViewModelFactory创建——这允许ViewModel在应用完全关闭后继续存在。

kotlin
class SearchViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    companion object {
        private val KEY_QUERY = string("search_query")
    }

    fun getSearchQuery(): String? = savedStateHandle[KEY_QUERY]

    fun saveSearchQuery(query: String) {
        savedStateHandle[KEY_QUERY] = query
    }
}

在代码中实现State Restoration

State Restoration的实际实现需要考虑几个方面:选择合适的存储、确定保存的数据量以及测试不同的关闭场景。让我们逐步看看如何使用state_restoration包为Flutter应用实现。

dart
class RestorableSearchField extends RestorableProperty<String> {
  String _value = '';

  @override
  String get value => _value;

  @override
  void set value(String newValue) {
    if (_value != newValue) {
      _value = newValue;
      notifyListeners();
    }
  }

  @override
  String? toPrimitives() => _value;

  @override
  void fromPrimitives(String? data) {
    _value = data ?? '';
  }
}

在实现时,重要的是要记住保存的边界。并非每个UI字段都需要恢复。长列表中的滚动位置——是。动画的临时状态——否。开发人员应有意识地选择哪些数据对用户体验至关重要,哪些可以在不损失便利性的情况下安全重置。

测试State Restoration是一项独立的任务,需要模拟进程终止。在Android中,可以通过adb shell am kill命令完成,在iOS中则通过Xcode中的终止模拟完成。诸如Espresso和XCTest等UI测试框架提供了专门的方法来检查状态恢复。

State Restoration最佳实践

第一条规则——保存标识符,而不是数据。与其保存具有数百个字段的完整对象,不如保存其唯一标识符,并在恢复时从数据库或API加载最新数据。这节省了Bundle中的空间,并保证了恢复时数据的时效性。

第二条规则——测试所有场景。检查屏幕旋转后的恢复、最小化一小时后返回后的恢复、以及系统因内存不足关闭应用后的恢复。每个场景可能因操作系统状态和可用资源的不同而表现不同。

第三条规则——使用系统机制,而不是自定义机制。iOS和Android提供了针对特定平台优化的内置State Restoration API。通过SharedPreferences或UserDefaults的自定义实现可能会导致同步问题和恢复时的意外行为。

第四条规则——处理状态缺失。在首次启动或清除数据后,状态可能不存在。UI应在初始状态下正常工作而不抛出异常。在使用前检查所有保存的数据是否为null,并提供默认值。

第五条规则——记录保存的键。当项目中有数十个屏幕且每个屏幕保存多个字段时,没有集中的键管理会导致混乱。在每个模块中为State Restoration创建一个包含键常量的统一类或文件。这简化了维护,并防止在重构时意外覆盖数据。

常见问题

移动应用中的State Restoration是什么?

State Restoration — 在应用重启或最小化后保存和恢复用户界面的机制,防止用户数据和工作上下文的丢失。

State Restoration与数据库保存有何不同?

State Restoration保存UI的临时状态(滚动位置、表单中输入的数据),而数据库保存用户的永久数据。State Restoration使用具有容量限制的系统机制(Bundle、NSData)。

如何在Android中实现State Restoration?

使用AndroidX Lifecycle中ViewModel中的SavedStateHandle。它在最小化时自动保存数据,并在返回时恢复。要支持完全重启,请使用SavedStateViewModelFactory。

如何在iOS中实现State Restoration?

在UIViewController中设置restorationIdentifier,并实现encodeRestorableState和decodeRestorableState方法。对于导航,使用NSUserActivity,并保存控制器堆栈中的路径。

在State Restoration时应保存哪些数据?

保存标识符,而不是完整数据:选定元素的ID、搜索查询、滚动位置、开关状态。避免保存大对象和图像。

总结

  • State Restoration — 在应用重启时保存和恢复UI的系统机制,对用户体验至关重要。
  • iOS — 使用UIStateRestoring协议和NSUserActivity保存导航和控制器数据。
  • Android — 在ViewModel中提供SavedStateHandle,用于自动保存和恢复状态。
  • Flutter — 支持RestorableProperty和RestorableStatefulWidget以保存小部件状态。
  • 限制 — 保存的数据大小有限制(Android上约50 KB),只应保存标识符。
  • 测试 — 必须检查所有场景:屏幕旋转、最小化、系统终止进程。
  • 策略 — 使用系统API,而不是通过文件或SharedPreferences的自定义实现。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读