在 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 架構的統一閉環。