在 Jetpack Compose 出现后,开发者可能会注意到一个变化:项目的主 Activity 默认从过去熟悉的 AppCompatActivity
变成了 ComponentActivity
。这个变化并非偶然,而是 Android 架构在向现代组件化演进过程中一个关键的转折点。本文将围绕 ComponentActivity
,深入讲解它的来历、意义以及它在 Jetpack 架构中的作用。
一、Activity 的演变简史
Android 应用的生命周期核心组件是 Activity
。随着 Android 框架的发展,Activity 的实现也经历了多个阶段的演进:
-
最初版本:Activity
- 提供基本的生命周期管理、UI 渲染能力。
- 但没有支持架构组件(如 ViewModel、LiveData、Lifecycle)的能力。
-
引入 Fragment 的 FragmentActivity
- 为支持 Fragment 的使用,Google 引入了
android.support.v4.app.FragmentActivity
。 - 后来演变为 AndroidX 中的
androidx.fragment.app.FragmentActivity
。
- 为支持 Fragment 的使用,Google 引入了
-
加入兼容特性的 AppCompatActivity
- 为支持向下兼容的主题、控件、ActionBar 等特性,
AppCompatActivity
出现。 - 是多数 XML 时代 UI 项目的默认基类。
- 为支持向下兼容的主题、控件、ActionBar 等特性,
-
四个类的简介及继承关系
-
Activity
Android 框架最原始的 Activity,提供最基本的组件生命周期管理,是所有 Activity 的基类。传统上开发者直接继承它来开发应用,但它的功能比较基础,没有内置对现代架构组件(如 Lifecycle、ViewModel 等)的支持。 -
ComponentActivity
引入较晚,作为一种扩展版的 Activity。它继承自 Activity,并内置了对 Android Architecture Components 的支持(例如 LifecycleOwner、SavedStateRegistryOwner 等)。ComponentActivity 专注于解耦业务逻辑和 UI 之间的关系,能更好地支持新一代的应用架构,也为 Compose 提供了简洁的入口。 -
FragmentActivity
继承自 Activity 的一个扩展类,主要目的是为 Activity 提供对 Fragment 的支持。FragmentActivity 随着 Android 支持库的出现而推出,目的是让旧版本的 Android 也能使用 Fragment 相关功能。 -
AppCompatActivity
是 FragmentActivity 的子类,属于 AndroidX AppCompat 库。它为应用提供了最新的 Material Design 组件和向下兼容的特性,例如支持 ActionBar、菜单主题和其他 UI 组件。很多旧项目基于 AppCompatActivity 来保持对老系统的兼容性,同时获得新 UI 组件支持。
-
二、为什么中途引入 ComponentActivity?
Jetpack 架构组件(如 ViewModel、Lifecycle、SavedState 等)最早在 2017 年推出,最初使用一些工具类(如 ViewModelProviders)在 Activity 中进行适配。但随着 Jetpack 架构体系逐渐成熟,Google 逐渐意识到:
需要一个统一、轻量、无 UI 依赖的 Activity 基类,来天然支持 Jetpack 架构组件。
ComponentActivity
来自于 AndroidX Activity 库,首次引入是在:
androidx.activity:activity:1.0.0
📅 发布于 2019年6月(在 Google I/O 2019 前后)
- 官方文档链接:https://developer.android.com/jetpack/androidx/releases/activity
- 它是 Jetpack 架构组件整合的一部分,起初目的是为支持 ViewModel、Lifecycle 等架构的注入。
早期的结构大致是这样的:
AppCompatActivity
↳ FragmentActivity
↳ Activity
而引入 ComponentActivity
后,变成了:
AppCompatActivity
↳ FragmentActivity
↳ ComponentActivity ← 新插入
↳ Activity
ComponentActivity
实现了多个接口,使得其具备以下能力:
- 是一个
LifecycleOwner
- 是一个
ViewModelStoreOwner
- 是一个
SavedStateRegistryOwner
- 是一个
OnBackPressedDispatcherOwner
这使得 Activity 不再需要借助辅助类,就可以天然使用 ViewModel、SavedState 等功能。
三、为什么 Compose 默认使用 ComponentActivity?
Compose 推出的目标是简化 UI 构建流程,同时完全脱离传统的 XML、Fragment 体系。
3.1 轻量化与现代架构支持
-
Compose 的轻量化思想
Compose 是一种声明式 UI 框架,它本身能够大幅简化 UI 的构建过程,不再需要通过 XML 和繁琐的视图树管理。如果项目全部采用 Compose 开发,许多传统由 Fragment 提供的“UI 组件化”方案就不再必需。 -
ComponentActivity 的优势
ComponentActivity 内置了对 Lifecycle、SavedStateRegistry 等现代架构组件的支持,这与 Compose 的声明式和状态驱动模式更契合。相比之下,AppCompatActivity 通常承载了历史遗留的兼容层,如果应用全用 Compose,这层兼容性反而成了额外的负担。
3.2 模板和标准化演进
-
官方模板的变更
以前的项目模板往往基于 AppCompatActivity,是因为当时大部分项目都需要兼容 Fragment 以及一些传统 UI 需求。随着 Compose 的推广,Google 推出了更精简的模板,默认选择 ComponentActivity,从而鼓励使用新架构和纯 Compose 代码。 -
降低复杂度
对于纯 Compose 应用,ComponentActivity 已经足够支撑诸如导航、状态保存等需求,不需要额外依赖 AppCompat 的兼容层,简化了依赖结构,也能减少应用体积。 -
一个 足够轻量 的 Activity,避免 UI 控件和兼容库的冗余依赖。
-
一个 完美兼容 Jetpack 架构组件 的容器。
于是,Compose 的推荐写法变成了:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyComposeApp()
}
}
}
这正是 Compose 使用 ComponentActivity
的原因:
它足够干净、足够现代,同时提供了 Compose 和 Jetpack 架构无缝连接的能力。
四、ComponentActivity 如何促进 ViewModel 使用方式演进?
既然 ViewModel 和 LiveData 更早就有,那为什么 ComponentActivity 要到 2019 年才引入来支持它们?
下面我详细解释一下时间线和背景👇
🕰️ ViewModel 和 LiveData 的引入时间
-
LiveData
- 首次引入版本:
android.arch.lifecycle:runtime:1.0.0
- 发布时间:2017年11月(Google I/O 2017 之后)
- 首次引入版本:
-
ViewModel
- 同样首次出现在
android.arch.lifecycle:viewmodel:1.0.0
- 发布时间也是:2017年11月
- 同样首次出现在
📦 它们当时是属于
android.arch.*
包名下,也就是 Jetpack 的 早期版本(现在都迁移到了androidx.*
包中)。
🤔 那为什么 ComponentActivity
要到 2019 年才出现?
原因是这样的:
✅ 1. 最初是通过 ViewModelHelpers 适配的
在 ViewModel 刚发布的时候,为了让开发者在不同类型的 Activity/Fragment 中用 ViewModel,Google 提供了“Helper 类”来协助获取:
ViewModelProviders.of(activity).get(MyViewModel::class.java)
这其实是通过“工具方法”来适配 FragmentActivity
或 AppCompatActivity
,不是通过统一的基类来支持架构组件。
✅ 2. 后来 Google 想系统性地整合架构组件支持
为了彻底解耦各种 Activity 的生命周期管理、状态保存、ViewModel 等支持,Google 决定:
抽出一个专门的基类
ComponentActivity
,来做为现代架构组件支持的通用基础。
这个类整合了:
LifecycleOwner
ViewModelStoreOwner
SavedStateRegistryOwner
OnBackPressedDispatcherOwner
(也支持 Compose 的 back handling)
它让所有 Activity 都可以天然具备使用架构组件的能力,不再依赖工具类或中间层。
- 你现在在 Compose 项目中可以直接这样写:
class MainActivity : ComponentActivity() {
val viewModel by viewModels<MyViewModel>()
...
}
这是 ComponentActivity
实现了 ViewModelStoreOwner
才能这么用,旧的 Activity
是不行的。
不但代码更简洁,而且可以更方便地与 SavedStateHandle
、ActivityResult
、LifecycleObserver
等 Jetpack 能力结合。
从此,ViewModel 与 Activity 的结合方式更加清晰、现代、类型安全。
五、小结
从 Activity
→ FragmentActivity
→ AppCompatActivity
的历史路径中,我们可以看出 Android 为适应不断变化的 UI 架构做出的调整。而 ComponentActivity
的加入,是 Jetpack 架构化进程中的一次重要升级:
- 它为 ViewModel、Lifecycle、SavedState 提供了统一支持
- 它是 Compose 的天然基座
- 它让现代开发变得更简单、更一致
可以说,没有 ComponentActivity
,就没有 Compose 时代 Jetpack 架构的统一闭环。