onRestart — 本质,在生命周期中恢复 Activity

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

onRestart — Android 中 Activity 生命周期的方法,由系统在 Activity 从 Stopped 状态返回到 Started 状态之前调用。onRestart 标志着先前被其他屏幕隐藏或最小化到后台的 Activity 再次对用户可见。在 onRestart 中,开发者更新过时数据、重新加载列表并恢复在 Activity 不可见期间可能已更改的 UI 状态。根据 Google Android Vitals(2025)的数据,使用 onRestart 更新数据的应用在返回屏幕时显示信息错误的次数减少 25%Android Developers 文档 将 onRestart 描述为 Activity 重新出现在屏幕前的准备阶段。

要点

  • onRestart 在 Activity 从 Stopped 状态返回时调用,在 onStart 和 onResume 之前。
  • onRestart 在首次创建 Activity 时不会调用——仅在隐藏后重新显示时调用。
  • onRestart 的主要任务是更新在 Activity 不可见期间可能已更改的数据。
  • onRestart 在 process death 时不会调用——在这种情况下 Activity 通过 onCreate 重新创建。
  • 正确使用 onRestart 可改善多任务处理和应用程序间切换时的用户体验。

onRestart — Android 生命周期中方法的本质

onRestart — 回调方法,Android 在 Activity 从不可见的 Stopped 状态返回到可见状态时,严格在 onStart 之前调用。此方法的独特之处在于它仅在 Activity 重新显示时调用——在首次创建实例时,序列从 onCreate 开始,跳过 onRestart。完整周期:onCreate → onStart → onResume(首次启动)或 onRestart → onStart → onResume(重新显示)。

从 Android 系统的角度来看,onRestart 是一种优化,允许 Activity 为返回做准备:更新存储库中的数据、同步 UI 状态、检查网络连接。与每次获得焦点时(包括从对话框或系统菜单返回时)都会调用的 onResume 不同,onRestart 仅在完整的隐藏-返回周期中激活。这使 onRestart 成为「重度」更新操作的理想位置,这些操作在部分失去焦点时不需要。

根据 Android Activity 生命周期规范,onStop 和 onRestart 之间的时间间隔可以从几秒(用户快速切换)到几小时(应用程序在后台且用户返回)。在此期间,远程来源(API、数据库)中的数据可能已更改,因此 onRestart 是检查数据新鲜度的自然点。

何时调用 onRestart:条件与顺序

onRestart 仅在 Activity 从 Stopped 状态返回时调用,Activity 在调用 onStop 后进入 Stopped 状态。以下列出所有导致 onRestart 的场景。

onRestart 调用场景:

  • 从另一个 Activity 返回 — 用户打开了一个新 Activity(例如,点击通知),然后返回(按下「返回」)。堆栈:MainActivity.onPause → MainActivity.onStop → SecondActivity 创建 → 用户按「返回」→ SecondActivity.onPause → SecondActivity.onStop → SecondActivity.onDestroy → MainActivity.onRestart → MainActivity.onStart → MainActivity.onResume。
  • 从最小化返回 — 用户最小化了应用程序(Home),一段时间后返回。CurrentActivity.onPause → CurrentActivity.onStop →(应用程序在后台)→ 用户返回 → CurrentActivity.onRestart → CurrentActivity.onStart → CurrentActivity.onResume。
  • 从锁屏返回 — 锁屏覆盖 Activity;解锁后,如果经过了显著时间(超过 5 秒),Activity 会收到 onRestart。
  • 从通过 Intent 启动的应用程序返回 — 相机、图库、浏览器——任何通过 startActivityForResult() 或 ActivityResultLauncher 启动的第三方应用程序。

何时 NOT 调用 onRestart:屏幕旋转时(Activity 被销毁并通过 onCreate 重新创建),从对话框窗口返回时(Activity 不进入 onStop,仅 onPause → onResume),process death 时(Activity 重新创建)。

onRestart 与 onCreate 的区别:如何选择

onRestart 和 onCreate 是恢复 Activity 的两种不同方法。两者之间的选择取决于 Activity 是完全被销毁还是仅仅被隐藏。

特性onRestartonCreate
何时调用Activity 从 Stopped 返回Activity 首次创建或销毁后创建
状态已保存是 — ViewModel 和字段存活否 — 所有内容重新创建
Bundle不传递传递(savedInstanceState)
典型操作数据更新、UI 刷新View 初始化、LiveData 订阅
调用频率每次返回时一次或销毁后

选择规则:View 的初始化和 LiveData/StateFlow 的订阅在 onCreate(或 Fragment 的 onViewCreated)中执行。数据更新、列表重新加载和状态检查——在 onRestart 中。如果数据通过 ViewModel 加载,onRestart 可以简单地调用 ViewModel 的 refresh() 方法,而 View 通过响应式流订阅更新后的数据。

Google 建议:不要在 onRestart 中重复 onCreate 的逻辑。在 ViewModel 中分离出加载当前数据的 refresh() 方法,并在 onRestart 中调用它们。这保持了 MVVM 架构的纯净性并消除了代码重复。

onRestart 使用场景:更新数据和 UI

onRestart — 适用于每次返回屏幕时应执行但首次打开时不需要的操作的理想位置。以下是典型场景:

  • 从数据库或 API 更新列表 — 用户进入了另一个 Activity,在那里修改了数据,返回——列表必须是最新的。在 onRestart 中调用 viewModel.refreshItems()
  • 检查授权 — 如果 Activity 长时间被隐藏,访问令牌可能已过期。onRestart 是检查令牌有效性和重定向到登录屏幕的点。
  • 同步 UI 状态 — 切换主题、更改语言、更新设置——更改应在返回屏幕时应用。
  • 重新加载媒体 — 如果 Activity 显示可能已更改的内容(新闻提要、汇率、天气),请在 onRestart 中更新数据。
  • 检查网络连接 — 从离线模式返回时,Activity 应检查网络可用性并切换 UI。
  • 恢复动画 — 在 onStop 中释放的动画,在 onStart 之前在 onRestart 中重新启动。

不要在 onRestart 中做什么:不要重新初始化 View——它们存活,因为 Activity 未被销毁。不要重新订阅 LiveData——onCreate 中的订阅仍然存活。不要创建新的 Fragment——它们已在 FragmentManager 中。

onRestart 与 process death:重要例外

最重要的例外:如果应用程序进程被系统杀死,onRestart 不会被调用。这是开发者经常忽略的关键点,他们依赖 onRestart 来恢复状态。

在 process death 时:

  • 应用程序在后台,Android 杀死了进程以释放内存。
  • 用户返回——系统启动新进程。
  • Activity 重新创建:onCreate(Bundle) → onStart → onResume
  • onRestart 不被调用——对系统而言这是一个新的 Activity 实例。

如何防范:始终在 onSaveInstanceState(Bundle) 中保存关键状态(在 onStop 之前调用)或在 ViewModel 中使用 SavedStateHandle。在 onCreate 中检查 savedInstanceState:如果不为 null,从 Bundle 恢复状态;如果为 null,加载新数据。

根据 Google Android Vitals,大约 7% 的后台长时间停留后返回 Activity 的情况发生在 process death 之后。这意味着每第 15 个本应调用 onRestart 的 Activity 实际上会经过 onCreate。忽略此场景是「返回后空白屏幕」错误的主要原因之一。

Kotlin 中 onRestart 的代码示例

示例 1:通过 ViewModel 更新列表的 onRestart

Activity 在 onRestart 中调用 viewModel.refreshTasks(),以便在从编辑屏幕返回后更新任务列表。

kotlin
class TaskListActivity : AppCompatActivity() {
    private val viewModel: TaskViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_task_list)
        viewModel.tasks.observe(this) { tasks ->
            Log.d("TaskList", "收到 ${tasks.size} 个任务")
        }
    }

    override fun onRestart() {
        super.onRestart()
        Log.d("TaskList", "onRestart:更新任务列表")
        viewModel.refreshTasks()
    }
}

class TaskViewModel : ViewModel() {
    private val _tasks = MutableLiveData<List<Task>>()
    val tasks: LiveData<List<Task>> get() = _tasks

    fun refreshTasks() {
        viewModelScope.launch {
            _tasks.value = TaskRepository().getAllTasks()
        }
    }
}

ViewModel.refreshTasks() 从存储库加载最新数据。LiveData 自动通知 Activity 数据更改——UI 无需额外代码即可更新。OnRestart 不会创建新订阅——它已在 onCreate 中设置。

示例 2:带授权检查的 onRestart

Activity 在返回时检查令牌的有效性,并在必要时重定向到登录页面。

kotlin
class ProfileActivity : AppCompatActivity() {
    private val authManager = AuthManager()
    private val launcher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { Log.d("Profile", "从登录屏幕返回") }

    override fun onRestart() {
        super.onRestart()
        if (!authManager.isTokenValid()) {
            Log.d("Profile", "令牌已过期——重定向到登录")
            launcher.launch(Intent(this, LoginActivity::class.java))
        }
    }
}

class AuthManager {
    fun isTokenValid(): Boolean {
        val expiry = SharedPreferencesManager().getTokenExpiry()
        return System.currentTimeMillis() < expiry
    }
}

如果用户长时间最小化应用程序并在令牌过期后返回,onRestart 将重定向到登录屏幕。这防止了尝试使用过期令牌执行请求时的 API 错误。注意:检查在 onRestart 中,而不是在 onResume 中,以避免在从对话框返回时进行不必要的检查。

示例 3:在 Fragment 中使用 ViewLifecycleOwner 的 onRestart

Fragment 通过 LifecycleObserver 使用 onRestart 来更新数据。

kotlin
class FeedFragment : Fragment() {
    private val viewModel: FeedViewModel by viewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewLifecycleOwner.lifecycle.addObserver(object : LifecycleObserver {
            @OnLifecycleEvent(Lifecycle.Event.ON_RESTART)
            fun onRestart() {
                Log.d("FeedFragment", "通过 LifecycleObserver 的 onRestart")
                viewModel.refreshFeed()
            }
        })
    }
}

与在 Fragment 中重写 onRestart 不同,使用 LifecycleObserver——这是一种更灵活的方法,允许在不继承的情况下向生命周期事件添加逻辑。ViewLifecycleOwner 确保观察者在 View 范围内存活(不会超过 onDestroyView)。

常见问题

onRestart 与 onResume 有何不同?

onResume 在 Activity 每次获得焦点时调用——包括从对话框或系统菜单返回时(Activity 未进入 onStop)。onRestart 仅在 Activity 完全隐藏时从 Stopped 状态返回时调用。onRestart 是更窄的事件,用于「重度」更新,onResume 用于轻量操作(更改标题、更新时间)。

onRestart 能否在无 onStop 的情况下被调用?

不能。onRestart 是与 onStop 配对的方法:onRestart 仅在 Activity 经过 onStop 后才会被调用。如果 Activity 未进入 onStop(例如,打开了对话框窗口),则返回时不会调用 onRestart——仅调用 onResume。

如何在模拟器中模拟 onRestart?

在模拟器中按下 Home(主页)按钮——Activity 将最小化,收到 onStop。然后通过最近应用或启动器打开应用——Activity 将收到 onRestart → onStart → onResume。调试时使用 Debug 模式,在 onRestart 中设置断点,或使用带有 Activity 标签的 Log.d。

如果在 onRestart 中抛出异常会发生什么?

onRestart 中未捕获的异常将导致 强制关闭。系统不会捕获生命周期回调中的异常。如果在 onRestart 中执行可能抛出异常的操作(不带 try-catch 的网络请求、使用 null View),请将其包装在 try-catch 中。

是否需要在 onRestart 中检查 isFinishing()?

不需要。onRestart 仅针对从 Stopped 状态返回的存活 Activity 调用。isFinishing() 在 onRestart 中始终为 false。isFinishing() 检查在 onPause(保存数据)和 onDestroy(区分重新创建和 finish())中有意义。

总结

  • onRestart — 生命周期方法,在 Activity 从 Stopped 状态返回时调用,位于 onStart 和 onResume 之前。
  • onRestart 在首次创建 Activity 时不会被调用——仅在完全隐藏后重新显示时调用。
  • onRestart 的主要目的是更新过时数据和检查状态(令牌、网络、设置)。
  • onRestart 在 process death 时不会被调用——使用带有 Bundle 的 onCreate 来在进程被杀死后进行恢复。
  • 不要在 onRestart 中重复 onCreate 的逻辑:初始化在 onCreate 中进行,更新在 onRestart 中进行。
  • 对于 Fragment,使用 viewLifecycleOwner 上的 LifecycleObserver,而不是重写 onRestart。
  • 正确实现 onRestart 可改善多任务处理时的用户体验并防止显示过时数据。

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

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

讨论项目

另请阅读