彻底讲懂 Activity
这篇文章写给所有还没真正“悟透” Activity 的 Android 开发者。
不论你是刚入门的新手,还是写了两年依然偶尔懵的老手,
看完这一篇,你会彻底理解:
Activity 是什么、怎么活的、怎么死的、以及系统是怎么管它的。
一、什么是 Activity?
一句话定义:
Activity = 用户与界面交互的窗口,是 Android 应用的核心存在。
你看到的每一个界面(比如登录页、设置页、朋友圈)
其实都是一个 Activity 或 Fragment 在屏幕上渲染出来的。
在底层,Activity 其实是一个被系统托管的「可见进程组件」。
它由 AMS(ActivityManagerService) 管理,
由 WMS(WindowManagerService) 控制显示,
并由 ApplicationThread / ActivityThread 实际执行。
二、Activity 的生命周期图
先上图👇
onCreate() → onStart() → onResume()
↓ ↑
onPause() ← onStop() ← onRestart()
↓
onDestroy()
这个流程是 Activity 从「出生 → 可见 → 交互 → 暂停 → 销毁」的完整旅程。
三、核心生命周期方法详解
三种稳定状态
Activity 的生命周期中,只有在以下三种状态之一,才能较长时间保持状态不变:
- Resumed(运行状态) :
Activity 处于前台,用户可以与其交互。 - Paused(暂停状态) :
Activity 被前台的半透明或未全屏的 Activity 部分遮挡。
暂停状态下不会接收用户输入,也无法执行任何代码。 - Stopped(停止状态) :
Activity 被完全隐藏,对用户不可见。
实例及成员变量会保留,但无法执行任何逻辑。
除此之外的其他阶段(例如 onCreate()、onStart())都是过渡状态(Transient States),
系统会很快进入下一个阶段,比如 onCreate() 后几乎立即调用 onStart()、onResume()。
各生命周期方法详解:
onCreate()
- 初始化阶段:创建视图、绑定 ViewModel、注册监听。
- 类似 iOS 的
viewDidLoad()。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("LifeCycle", "onCreate")
}
建议:只初始化一次,不做耗时操作。
onStart()
- Activity 开始对用户可见。
- 但还不能交互(比如弹出窗口遮挡)。
onResume()
- Activity 进入前台、可交互 状态。
- 所有动画、相机、传感器、监听器通常在此处启动。
onPause()
- Activity 失去焦点(例如跳转新界面、弹出对话框)。
- 必须 立即释放资源(比如暂停播放视频)。
onStop()
- Activity 完全不可见。
- 可以在这里释放 UI 相关资源、保存数据。
onDestroy()
-
Activity 被系统销毁。
-
注意:不是每次离开页面都会调用!
- 用户按返回键 → 会调用
- 旋转屏幕重建 → 原 Activity onDestroy,新的 onCreate
四、Activity 的四种启动模式(launchMode)
在 AndroidManifest.xml 里定义:
| 启动模式 | 特点 | 适用场景 |
|---|---|---|
| standard | 默认,每次启动都会创建新实例 | 普通页面 |
| singleTop | 栈顶已存在则复用 | 消息详情页 |
| singleTask | 整个任务栈内唯一 | 首页、MainActivity |
| singleInstance | 独立任务栈,系统级复用 | 唤起第三方页面,如视频播放页 |
示例:
<activity
android:name=".MainActivity"
android:launchMode="singleTask" />
五、Activity 的栈结构(Task Stack)
系统维护了一个 任务栈(Task Stack) 来管理 Activity。
- 新启动的 Activity 会被压入栈顶。
- 用户按返回键,会出栈回到上一个 Activity。
- 不同 launchMode 决定是否复用已有实例。
可视化理解:
[HomeActivity]
↑
[ProfileActivity]
↑
[SettingsActivity] ← 当前界面
返回键:销毁 SettingsActivity → 回到 ProfileActivity
六、Activity 是如何被系统启动的(原理流程)
整个流程看似简单,其实非常经典👇
点击启动App →
Launcher进程调用 AMS →
AMS 通知 Zygote fork 新进程 →
新进程启动 ActivityThread →
ActivityThread 创建 Application →
Instrumentation.newActivity() →
Activity.onCreate() ...
关键组件说明:
- AMS:ActivityManagerService,系统的大管家,管理四大组件。
- Zygote:Android 的孵化器,负责创建新进程。
- ActivityThread:应用主线程,负责消息分发与生命周期回调。
- Instrumentation:系统钩子,用于监控 Activity 的创建与行为。
七、配置变化与重建(屏幕旋转)
旋转屏幕或切换语言会触发 Activity 重建。
onPause → onStop → onDestroy → onCreate → onStart → onResume
解决办法:
-
禁止重建
android:configChanges="orientation|screenSize" -
保存状态
override fun onSaveInstanceState(outState: Bundle) { outState.putString("text", "Hello") }
八、常见坑点与避坑建议
| 场景 | 问题 | 解决方案 |
|---|---|---|
| 屏幕旋转 | Activity 重建导致数据丢失 | 用 ViewModel 或 onSaveInstanceState 保存状态 |
| 异步回调 | Activity 销毁后仍回调 UI | 判断 isFinishing() |
| 多 Activity 跳转 | 栈混乱 | 理解 launchMode,或使用 Navigation 组件 |
| 后台切换 | 生命周期混乱 | 善用 onPause/onStop,区分“可见”和“不可见”状态 |
九、现代 Activity:与 Jetpack 的关系
- 现在推荐用 ComponentActivity / AppCompatActivity
- 配合 ViewModel + Lifecycle + LiveData + Navigation 使用
- 生命周期完全受
LifecycleOwner管理
示例:
class MainActivity : ComponentActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Text(viewModel.text)
}
}
}
十、总结一句话
Activity 是 Android 应用的灵魂。
它负责:
- 承载 UI
- 维系生命周期
- 被系统严格托管
彻底理解 Activity,
你就真正理解了 Android 应用是怎么「活着」的。
互动区
你踩过最难调的 Activity 生命周期 Bug 是什么?
比如「后台切换回来 UI 全空」或者「旋转一次直接崩」??
评论区分享一下你的坑,我们一起补上!