onRestart — Android 中 Activity 生命周期的方法,由系统在 Activity 从 Stopped 状态返回到 Started 状态之前调用。onRestart 标志着先前被其他屏幕隐藏或最小化到后台的 Activity 再次对用户可见。在 onRestart 中,开发者更新过时数据、重新加载列表并恢复在 Activity 不可见期间可能已更改的 UI 状态。根据 Google Android Vitals(2025)的数据,使用 onRestart 更新数据的应用在返回屏幕时显示信息错误的次数减少 25%。Android Developers 文档 将 onRestart 描述为 Activity 重新出现在屏幕前的准备阶段。
要点
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 仅在 Activity 从 Stopped 状态返回时调用,Activity 在调用 onStop 后进入 Stopped 状态。以下列出所有导致 onRestart 的场景。
onRestart 调用场景:
何时 NOT 调用 onRestart:屏幕旋转时(Activity 被销毁并通过 onCreate 重新创建),从对话框窗口返回时(Activity 不进入 onStop,仅 onPause → onResume),process death 时(Activity 重新创建)。
onRestart 和 onCreate 是恢复 Activity 的两种不同方法。两者之间的选择取决于 Activity 是完全被销毁还是仅仅被隐藏。
| 特性 | onRestart | onCreate |
|---|---|---|
| 何时调用 | 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 — 适用于每次返回屏幕时应执行但首次打开时不需要的操作的理想位置。以下是典型场景:
viewModel.refreshItems()。不要在 onRestart 中做什么:不要重新初始化 View——它们存活,因为 Activity 未被销毁。不要重新订阅 LiveData——onCreate 中的订阅仍然存活。不要创建新的 Fragment——它们已在 FragmentManager 中。
最重要的例外:如果应用程序进程被系统杀死,onRestart 不会被调用。这是开发者经常忽略的关键点,他们依赖 onRestart 来恢复状态。
在 process death 时:
如何防范:始终在 onSaveInstanceState(Bundle) 中保存关键状态(在 onStop 之前调用)或在 ViewModel 中使用 SavedStateHandle。在 onCreate 中检查 savedInstanceState:如果不为 null,从 Bundle 恢复状态;如果为 null,加载新数据。
根据 Google Android Vitals,大约 7% 的后台长时间停留后返回 Activity 的情况发生在 process death 之后。这意味着每第 15 个本应调用 onRestart 的 Activity 实际上会经过 onCreate。忽略此场景是「返回后空白屏幕」错误的主要原因之一。
Activity 在 onRestart 中调用 viewModel.refreshTasks(),以便在从编辑屏幕返回后更新任务列表。
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 中设置。
Activity 在返回时检查令牌的有效性,并在必要时重定向到登录页面。
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 中,以避免在从对话框返回时进行不必要的检查。
Fragment 通过 LifecycleObserver 使用 onRestart 来更新数据。
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)。
常见问题
onResume 在 Activity 每次获得焦点时调用——包括从对话框或系统菜单返回时(Activity 未进入 onStop)。onRestart 仅在 Activity 完全隐藏时从 Stopped 状态返回时调用。onRestart 是更窄的事件,用于「重度」更新,onResume 用于轻量操作(更改标题、更新时间)。
不能。onRestart 是与 onStop 配对的方法:onRestart 仅在 Activity 经过 onStop 后才会被调用。如果 Activity 未进入 onStop(例如,打开了对话框窗口),则返回时不会调用 onRestart——仅调用 onResume。
在模拟器中按下 Home(主页)按钮——Activity 将最小化,收到 onStop。然后通过最近应用或启动器打开应用——Activity 将收到 onRestart → onStart → onResume。调试时使用 Debug 模式,在 onRestart 中设置断点,或使用带有 Activity 标签的 Log.d。
onRestart 中未捕获的异常将导致 强制关闭。系统不会捕获生命周期回调中的异常。如果在 onRestart 中执行可能抛出异常的操作(不带 try-catch 的网络请求、使用 null View),请将其包装在 try-catch 中。
不需要。onRestart 仅针对从 Stopped 状态返回的存活 Activity 调用。isFinishing() 在 onRestart 中始终为 false。isFinishing() 检查在 onPause(保存数据)和 onDestroy(区分重新创建和 finish())中有意义。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。