Activity相关知识

65 阅读5分钟

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。为了避免数据丢失,系统提供了 onSaveInstanceStateonRestoreInstanceState 方法来保存和恢复临时状态。

  • 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

  • TaskAffinitysingleTask启动模式配对使用的时候,它是具有该模式的Activity的目前任务栈的名字,待启动的Activity会运行在名字和TaskAffinity相同的任务栈中。
  • TaskAffinityallowTaskReparenting 配合使用时,可以允许一个 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的建议是尽量使用显式调用方式来启动服务。