Activity生命周期
1. 核心生命周期方法
Activity 的生命周期由以下几个主要方法组成:
onCreate(Bundle savedInstanceState):Activity的入口点,通常用于初始化界面和数据。我们在这里通过setContentView()设置布局,初始化视图组件,配置业务逻辑等。如果savedInstanceState不为null,则表示Activity可能是由于配置变化或内存回收后重建的,开发者可以在这里恢复非 UI 相关的状态。onStart():Activity进入“可见”状态时调用,但用户还无法进行交互。适合在此做一些准备工作,如启动 UI 动画、注册广播接收器等。onResume():Activity进入“可交互”状态时调用。此时,界面完全展示给用户,用户可以与应用交互。可以在此恢复界面相关的实时操作,如视频播放或传感器监听等。onPause(): 当Activity进入后台(如打开新页面或屏幕关闭)时调用。通常在此释放用户不可见的资源,停止动画、保存用户输入等,确保下次恢复时状态一致。onStop():Activity完全不可见时调用。此时适合做较重的资源释放,如关闭数据库、取消网络连接等。onDestroy():Activity被销毁时调用。通常用于最终的清理工作,如取消任务、释放内存等。它可能是因为用户主动退出或系统资源不足导致的销毁。
2. onSaveInstanceState() 和 onRestoreInstanceState()
Android 系统会在某些情况下(如配置变化、内存不足)自动销毁和重建 Activity。为了避免数据丢失,系统提供了 onSaveInstanceState 和 onRestoreInstanceState 方法来保存和恢复临时状态。
-
onSaveInstanceState(Bundle outState): 当Activity由于异常情况(如屏幕旋转、内存不足)被销毁时,系统会调用这个方法保存当前状态。你可以在这里保存 UI 状态(如滚动位置、用户输入等)。 -
onRestoreInstanceState(Bundle savedInstanceState): 当Activity被重建时,系统会调用这个方法来恢复之前保存的 UI 状态。它在onStart()之后调用,适合用于恢复用户界面相关的状态,如表单输入或列表的滚动位置。虽然
onCreate中也能恢复数据,但官方推荐在onRestoreInstanceState中恢复 UI 状态,因为此时界面已经完全初始化。
3. 完整的生命周期流程
当用户首次启动 Activity 时,生命周期的顺序是:
onCreate() → onStart() → onResume()(此时Activity可见且可交互)
当用户退出 Activity 或打开其他界面时:
onPause() → onStop() → onDestroy()
如果只是临时离开,如锁屏或打开其他短暂窗口,后续可能会调用:
onRestart() → onStart() → onResume()(重新进入交互状态)
4. 数据保存与恢复的建议
- 初始化操作:放在
onCreate中,确保在Activity创建时执行。 - 恢复 UI 状态:放在
onRestoreInstanceState中,确保 UI 恢复时界面已经初始化。 - 保存状态:放在
onSaveInstanceState中,保存易丢失的短暂状态,如输入框内容、滚动位置等。
注意:Activit(A) → Activity(B): onPause(A) → onCreate(B) → onStart(B) → onResume(B) → onStop(A)
Activity 可见和在前台的区别
可见 (Visible)
-
定义:Activity 是可见的,但不一定是当前用户正在交互的 Activity。
-
生命周期方法:
onStart():当 Activity 即将变得可见时调用。onStop():当 Activity 即将不再可见时调用。
处于可见状态的 Activity 仍然可以被用户看到,但可能在后台 Activity 之下(例如,用户打开了一个对话框或其他透明的 Activity),这时 Activity 处于可见状态但不在前台。
在前台 (Foreground)
-
定义:Activity 是可见的并且是用户当前正在交互的 Activity。
-
生命周期方法:
onResume():当 Activity 开始与用户交互时调用。onPause():当系统即将开始继续其他 Activity(即当前 Activity 将不再与用户交互)时调用。
一个 Activity 只有在
onResume()和onPause()之间的时间段内才处于前台状态。这意味着用户当前正在与该 Activity 交互,它位于任务栈的顶部,并且没有其他 Activity 覆盖它。
这两个状态的关键区别在于是否正在与用户交互。在前台状态表示完全控制权和交互权,而可见状态只是表示用户仍然能看到 Activity 的内容。
LaunchMode
- standard: 每次启动
Activity时都会创建新的实例,允许在任务栈中存在多个同类型的实例。 - singleTop: 已有实例时复用该实例,不会创建新实例,并通过
onNewIntent处理新的Intent。 - singleTask: 任务栈中只有一个该实例,若已存在则会复用并将其上面的所有活动弹出。
- singleInstance: 在整个系统中仅保留一个该实例,且其任务栈中只包含该实例,不允许有其他活动与其共享同一任务栈。
TaskAffinity
- 当
TaskAffinity和singleTask启动模式配对使用的时候,它是具有该模式的Activity的目前任务栈的名字,待启动的Activity会运行在名字和TaskAffinity相同的任务栈中。 TaskAffinity与allowTaskReparenting配合使用时,可以允许一个Activity在不同应用之间转移任务栈,使其能够从启动它的应用的任务栈移动到目标应用的任务栈中。
Activity的Flags
IntentFilter匹配规则
Action
action的匹配要求Intent中的action存在且必须和过滤规则中的其中一个action相同
Category
Intent可以没有category,如果有category,每个都要能够和过滤规则中的任何一个category相同
Data
data的匹配规则和action类似,如果过滤规则中定义了data,那么Intent中必须也要定义可匹配的data。
data语法:
<data android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:mimeType="string" />
data由两部分组成,mimeType和URI
URI结构:
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
注意: Intent-filter的匹配规则对于Service和BroadcastReceiver也是同样的道理,不过系统对于Service的建议是尽量使用显式调用方式来启动服务。