自从 Google 在2018年推出 Jetpack 之后,它就成为了 Android 未来发展的风向标。同时 Google 也希望借助 Jetpack 统一开发者开发规范,可以说,如果还想在 Android 界驰骋沙场,Jetpack 是我们必须要掌握的杀招。
一、Jetpack 概述
1.1 为什么需要 Jetpack
在 Jetpack 诞生之前,Android 开发面临几个核心痛点:
碎片化问题:Android 生态中设备碎片化、API 级别碎片化、开发模式碎片化。同一功能(如后台任务)在不同 API 级别上需要不同的实现方式(AlarmManager、JobScheduler、Firebase JobDispatcher 等),开发者需要编写大量兼容性代码。
生命周期管理困难:Activity/Fragment 的生命周期极其复杂,在配置变更(屏幕旋转、语言切换)时数据容易丢失,异步任务回调时 Activity 可能已销毁,导致 NPE 崩溃和内存泄露。
样板代码泛滥:findViewById、手动管理 FragmentTransaction 返回栈、SQLiteOpenHelper 编写重复的 CRUD 代码、为保留配置变更数据手动覆写 onSaveInstanceState 等,大量低价值的模板代码占据了开发时间。
架构不统一:缺乏官方推荐的架构指导,MVC、MVP、MVVM 各阵营争执不下,新人上手成本高,不同项目间的代码风格差异巨大。
Jetpack 正是在此背景下诞生:Google 将 Support Library 重构为 AndroidX,并在此基础上推出了一系列涵盖架构、UI、行为、基础四个领域的组件库集合,统称为 Jetpack。
1.2 Jetpack 的设计原则
Jetpack 的设计遵循四个核心原则:
向后兼容:绝大部分 Jetpack 组件兼容至 API 14(Android 4.0),个别组件(如 CameraX)需要 API 21+。Jetpack 通过内部兼容性封装,让开发者在旧设备上也能使用新 API 行为。
生命周期感知:Lifecycle 是 Jetpack 的基石。LiveData、ViewModel、WorkManager 等都是生命周期感知的,框架自动管理订阅/取消订阅,开发者无需关心生命周期同步问题。
模块化与解耦:每个 Jetpack 组件独立发布、独立语义化版本(Semantic Versioning)。开发者按需引入,不会因为引入一个组件而被强制升级整个套件。
最佳实践内置:Jetpack 组件封装了经过大量实战验证的最佳实践。例如 Room 在编译期验证 SQL 语法、Paging 内置了 DiffUtil 增量更新、WorkManager 自动选择最优调度器。
1.3 Jetpack 组件全景图
Jetpack 组件按功能分为四大类别:
Architecture(架构组件)
| 组件 | 说明 |
|---|---|
| Lifecycle | 生命周期感知基类,所有生命周期感知组件的基石 |
| LiveData | 生命周期感知的可观察数据持有者 |
| ViewModel | 管理 UI 数据,在配置变更时存活 |
| Room | SQLite 对象映射库,编译期 SQL 验证 |
| Paging | 分页加载库,支持本地/网络混合数据源 |
| Navigation | Fragment/Compose 导航管理 |
| WorkManager | 后台任务调度(保证执行) |
| DataStore | 替代 SharedPreferences 的键值/类型安全存储 |
| DataBinding | 声明式 UI 数据绑定 |
Foundation(基础组件)
| 组件 | 说明 |
|---|---|
| AppCompat | 向后兼容的 Activity/Fragment 基类 |
| Android KTX | Kotlin 扩展函数集,简化 API 调用 |
| Multidex | 突破 64K 方法数限制 |
| Test | Android 测试库 |
| Security | 加密 SharedPreferences 和文件 |
| Startup | 应用启动时初始化依赖 |
Behavior(行为组件)
| 组件 | 说明 |
|---|---|
| CameraX | 相机 API 封装,向后兼容 |
| DownloadManager | 长时间下载任务管理 |
| Media & Playback | 媒体播放(Media3/ExoPlayer) |
| Notifications | 通知栏管理与样式化 |
| Permissions | 权限请求封装 |
| Preferences/Settings | 用户偏好设置 |
| Sharing | 分享操作 |
UI(界面组件)
| 组件 | 说明 |
|---|---|
| Fragment | 模块化 UI 容器 |
| Layout (ConstraintLayout) | 高性能布局 |
| Animation & Transitions | 动画与过渡 |
| Emoji | 新版 Emoji 兼容 |
| WebView | 系统 WebView 封装 |
| Compose | 声明式 UI 工具包(下一代 UI 框架) |
| Palette | 从图片提取配色方案 |
二、AndroidX 迁移完全指南
2.1 Support Library 到 AndroidX 的背景
从 Android 1.0 开始,Google 提供了 android.support.* 包(Support Library)来向旧版本设备提供新 API 功能。但随着时间推移,Support Library 暴露出严重问题:
- 统一版本号枷锁:所有 Support Library 库共享同一个版本号(如
28.0.0),即使某个库没有变更也必须跟着升级。 - 包名与系统类冲突:
android.support.v4.app.Fragment与系统android.app.Fragment名称相似,容易混淆。 - 维护成本高:Support Library 被大量第三方库依赖,升级一个库可能触发连锁依赖冲突。
AndroidX 是 Support Library 的重写版本,使用 androidx.* 包命名空间,每个组件独立语义化版本控制。AndroidX 从 Android 9.0(API 28)开始被积极推广,Support Library 28.0.0 是最后一个版本,之后停止维护。
2.2 关键包名映射表
从 Support Library 迁移到 AndroidX 最核心的工作是包名替换:
| Support Library 包名 | AndroidX 包名 |
|---|---|
android.support.v4.app.Fragment |
androidx.fragment.app.Fragment |
android.support.v4.app.FragmentActivity |
androidx.fragment.app.FragmentActivity |
android.support.v7.app.AppCompatActivity |
androidx.appcompat.app.AppCompatActivity |
android.support.v7.widget.RecyclerView |
androidx.recyclerview.widget.RecyclerView |
android.support.v7.widget.Toolbar |
androidx.appcompat.widget.Toolbar |
android.support.v7.widget.CardView |
androidx.cardview.widget.CardView |
android.support.design.widget.CoordinatorLayout |
androidx.coordinatorlayout.widget.CoordinatorLayout |
android.support.design.widget.FloatingActionButton |
com.google.android.material.floatingactionbutton.FloatingActionButton |
android.support.constraint.ConstraintLayout |
androidx.constraintlayout.widget.ConstraintLayout |
android.support.v4.content.LocalBroadcastManager |
androidx.localbroadcastmanager.content.LocalBroadcastManager |
android.support.test.runner.AndroidJUnitRunner |
androidx.test.runner.AndroidJUnitRunner |
android.support.v4.view.ViewPager |
androidx.viewpager.widget.ViewPager |
android.support.v4.widget.SwipeRefreshLayout |
androidx.swiperefreshlayout.widget.SwipeRefreshLayout |
android.arch.lifecycle.LiveData |
androidx.lifecycle.LiveData |
android.arch.lifecycle.ViewModel |
androidx.lifecycle.ViewModel |
android.arch.persistence.room.RoomDatabase |
androidx.room.RoomDatabase |
2.3 组件 Artifact 映射表
除了包名变化外,Gradle 的依赖坐标也需要对应迁移:
| Support Library Artifact | AndroidX Artifact |
|---|---|
com.android.support:appcompat-v7:28.0.0 |
androidx.appcompat:appcompat:1.7.0 |
com.android.support:recyclerview-v7:28.0.0 |
androidx.recyclerview:recyclerview:1.3.2 |
com.android.support:cardview-v7:28.0.0 |
androidx.cardview:cardview:1.0.0 |
com.android.support:design:28.0.0 |
com.google.android.material:material:1.12.0 |
com.android.support:support-v4:28.0.0 |
androidx.legacy:legacy-support-v4:1.0.0 |
com.android.support.constraint:constraint-layout:1.1.3 |
androidx.constraintlayout:constraintlayout:2.1.4 |
com.android.support:multidex:1.0.3 |
androidx.multidex:multidex:2.0.1 |
android.arch.lifecycle:extensions:1.1.1 |
androidx.lifecycle:lifecycle-extensions:2.2.0(已废弃,改用具体组件) |
android.arch.persistence.room:runtime:1.1.1 |
androidx.room:room-runtime:2.6.1 |
android.arch.navigation:navigation-fragment:1.0.0 |
androidx.navigation:navigation-fragment:2.7.7 |
注意 Design 库的迁移路径:com.android.support:design 不仅改了包名,还改了 GroupId —— 变成 com.google.android.material:material。这是 Google 将 Material Design 组件从 AppCompat 中独立出来的产物。
2.4 Jetifier 深度解析
Jetifier 是 Android Gradle Plugin(AGP)内置的一个构建期字节码转换工具。当启用 android.enableJetifier=true 后,AGP 在编译过程中会扫描所有依赖(包括 AAR 和 JAR)的字节码,将 Support Library 类名、包名、资源引用自动迁移到 AndroidX 对应项。
Jetifier 的工作原理:
- 解析所有传递依赖的
.jar和.aar文件 - 对每个 class 文件执行 ASM 字节码扫描
- 匹配预定义的转换规则表(由 Google 维护)
- 改写类名、方法签名、字段类型中的 Support 引用
- 改写布局 XML 和资源引用
- 输出转换后的依赖给后续编译流程
Jetifier 的配置:
# gradle.properties |
注意:Jetifier 会增加构建时间(每个依赖都需要扫描转换),因此一旦项目中所有依赖都已原生支持 AndroidX,应该关闭 Jetifier:
android.enableJetifier=false |
可以通过 Gradle 的 dependencies 任务检查是否有依赖仍引用 Support Library:
./gradlew :app:dependencies --configuration releaseRuntimeClasspath | grep "com.android.support" |
2.5 Android Studio 自动迁移工具
Android Studio 提供了 “Refactor → Migrate to AndroidX” 一键迁移功能。该工具会:
- 将所有依赖坐标从 Support 替换为 AndroidX
- 替换源代码中所有 import 语句和类引用
- 替换 XML 布局中的控件类名
- 替换 Gradle 文件中的依赖声明
- 生成
.idea/migrateToAndroidX.xml记录迁移状态
迁移前务必:
- 将项目完全 commit 到版本控制
- 备份
gradle.properties - 更新 AGP 到 3.2.0 以上
- 确保 compileSdkVersion >= 28
迁移后验证:
- 检查
build.gradle中是否仍有com.android.support坐标 - 搜索源代码中是否仍有
android.supportimport - 搜索布局 XML 中是否仍有
android.support.*类名 - Gradle Sync + Build 看是否报错
- 运行 Lint 检查:
./gradlew lint
三、构建系统配置
3.1 Gradle Build 脚本配置
根项目 build.gradle.kts:
// 根项目 build.gradle.kts |
gradle.properties 关键配置:
# AndroidX 必需 |
3.2 Version Catalog(libs.versions.toml)
Gradle 7.0+ 引入 Version Catalog 作为官方推荐的依赖版本管理方案。在 gradle/libs.versions.toml 中集中管理:
# gradle/libs.versions.toml |
3.3 BOM(Bill of Materials)统一版本管理
对于 Jetpack 中版本高度耦合的组件(如 Compose、Lifecycle),Google 提供了 BOM 依赖。BOM 本质上是一个 POM 文件,声明了一组库的统一版本:
// 使用 Compose BOM,无需逐个指定 Compose 组件版本 |
Compose 的 BOM 使用 platform() 声明,这样所有 Compose 组件的版本都来自同一个 BOM,保证兼容性。
Lifecycle 也有类似的 BOM 机制(通过版本号对齐),也可以通过定义 ext 变量的方式批量管理:
// build.gradle.kts 中 ext 方式(适用于版本一致的系列) |
3.4 buildSrc 约定插件
对于大型多模块项目,推荐创建 buildSrc 目录管理公共构建配置。但更现代的做法是创建包含约定插件(Convention Plugin)的独立模块。
. |
android-application.gradle.kts(约定插件示例):
// build-logic/convention/src/main/kotlin/android-application.gradle.kts |
四、多模块项目架构
4.1 推荐的模块划分
Google 推荐的架构中,应将应用划分为多个 Gradle Module:
:app # Application 入口,依赖注入装配 |
4.2 模块依赖关系
:app |
核心约束:
:feature:*模块只依赖:core:domain和:core:ui:core:domain不依赖任何 Android 框架(纯 Kotlin/Java 模块):core:data实现:core:domain中定义的接口(依赖反转):app通过 Hilt 完成依赖注入的装配
4.3 每个模块的 build.gradle.kts 示例
:core:domain(纯 Kotlin 模块):
plugins { |
:core:data(Android Library):
plugins { |
五、Compose vs View 体系决策指南
5.1 何时选择 Jetpack Compose
适合 Compose 的场景:
- 全新项目,没有历史遗留代码
- UI 复杂度高,状态管理需求突出
- 需要大量动画与自定义绘制
- 团队已熟悉 Kotlin 与声明式 UI 范式
- 需要跨平台(Compose Multiplatform)
Compose 的核心优势:
- 声明式 UI:描述 UI 应该是什么样,框架负责增量更新
- 无 XML:代码即 UI,减少文件跳转,重构更安全
- 强大的状态管理:
remember、mutableStateOf、StateFlow.collectAsState() - 原生性能:Compose 编译器将 Composable 编译为高效的树更新逻辑
- 与 View 互操作:
AndroidView/ComposeView双向嵌入
5.2 何时保留 View 体系
适合传统 View 体系的场景:
- 大型存量项目,已有大量 XML 布局和自定义 View
- 团队尚未掌握 Compose(学习曲线)
- 需要使用尚未 Compose 友好的第三方库(如某些地图 SDK)
- 需要 WebView 重交互场景(Compose 的 WebView 封装仍不够完善)
- 有大量使用 DataBinding 的已有代码
5.3 渐进式迁移策略
从 View 向 Compose 渐进迁移的路线图:
- 底部 Sheet / 弹窗:先用 Compose 编写 Dialog、BottomSheet,通过
DialogFragment+ComposeView桥接。 - 列表 Item:在 RecyclerView 中通过
ComposeView渲染单个 item。 - 独立页面:新建功能页面直接用 Compose Fragment(
fragment-compose提供了ComponentActivity.setContent等价物)。 - 主页面:将主要的 Fragment 逐步替换为 Compose。
- Navigation:迁移到
navigation-compose,告别 Fragment。
5.4 兼容性桥接代码
在 XML 中嵌入 Compose:
<androidx.compose.ui.platform.ComposeView |
binding.composeView.setContent { |
在 Compose 中嵌入 View:
|
六、项目初始化 Checklist
启动一个 Jetpack 新项目的完整检查清单:
6.1 环境准备
- Android Studio Hedgehog (2023.1.1) 或更新版本
- Gradle 8.5+ / AGP 8.5+
- Kotlin 2.0+
- compileSdk = 34, targetSdk = 34, minSdk = 24
- 创建 Version Catalog (
gradle/libs.versions.toml)
6.2 基础配置
-
gradle.properties:android.useAndroidX=true - 引入 AppCompat、Material Design、ConstraintLayout
- 引入 Lifecycle + ViewModel + LiveData KTX
- 引入 Navigation + Safe Args 插件
- 配置 Hilt 依赖注入
- KSP 替代 kapt(提升编译速度)
6.3 架构搭建
- 创建多模块目录结构
- 配置 build-logic 约定插件
- 创建 Application 类,添加
@HiltAndroidApp - 实现 Single Activity 架构(MainActivity + NavHost)
- 定义 Theme / 颜色系统
- 配置 CI pipeline(GitHub Actions / Jenkins)
6.4 代码规范
-
ktlint或detekt静态检查 -
.editorconfig统一代码风格 - Git hooks pre-commit 检查
- 编写 README 与架构文档(建议使用 PlantUML 或 Mermaid)
面试常考问题
Q1:AndroidX 与 Support Library 的区别?
AndroidX 是 Support Library 的升级版,核心区别:
- 包名从
android.support.*变为androidx.* - 独立语义化版本控制,每个组件可独立升级
- Support 28.0.0 之后停止维护
- Jetifier 工具可在编译期将 Support 引用自动转换为 AndroidX
- Design 库拆分为独立的 Material Components(
com.google.android.material:material) - ViewPager 拆分为 ViewPager2(基于 RecyclerView,支持垂直滑动和 RTL)
Q2:enableJetifier 的作用是什么?
Jetifier 在构建过程中扫描所有依赖的字节码,将 Support Library 类名、包名、资源引用自动迁移到 AndroidX 对应项:
- 解析 AAR/JAR 文件中的 class 字节码
- 查找 Support Library 类引用(如
android.support.v7.app.AppCompatActivity) - 替换为对应 AndroidX 类引用(如
androidx.appcompat.app.AppCompatActivity) - 同时改写资源引用和布局 XML
适用于依赖了尚未迁移 AndroidX 的第三方库的场景。当所有依赖都原生支持 AndroidX 后应关闭以提升构建速度。AOSP 源码路径:frameworks/support/ 目录(现已整体迁移为 AndroidX 仓库)。
Q3:Jetpack Compose 与传统 View 体系如何共存?
- Compose → View:通过
ComposeView(一个 ViewGroup 子类)将 Composable 内容嵌入传统布局,调用composeView.setContent { ... } - View → Compose:通过
AndroidViewComposable 将传统 View 嵌入 Compose 树 - Activity:
ComponentActivity.setContent { ... }替代setContentView() - Fragment:引入
androidx.fragment:fragment-compose,Fragment 中使用onCreateView返回ComposeView - Navigation:
navigation-compose提供 NavHost Composable,无需 Fragment - 推荐策略:新页面用 Compose,存量页面保持 View,通过互操作机制渐进迁移
Q4:Version Catalog 相比 buildSrc 的优势?
Version Catalog(libs.versions.toml)是 Gradle 7.0 引入的官方方案:
- 声明式配置,无需编译,IDE 自动提示
- Gradle 原生支持,不需要额外插件
- 可通过
libs.versions.xxx在 settings.gradle.kts 中访问 - buildSrc 每次变更都要重新编译整个构建逻辑,Version Catalog 则无需
- 两者可以共存:Version Catalog 管理版本号,buildSrc/convention plugins 管理构建逻辑
Q5:DataBinding vs ViewBinding 如何选择?
- ViewBinding:轻量、编译快,仅生成 View 引用类,无布局表达式,适合不需要数据驱动的场景
- DataBinding:功能全(布局表达式、双向绑定、BindingAdapter),构建速度较慢,适合 MVVM 中数据需要驱动 UI 的场景
- 底线:如果不需要布局表达式和双向绑定,直接用 ViewBinding,切勿为了 DataBinding 而 DataBinding
- Compose 项目中两者都不需要 —— Compose 本身通过状态驱动 UI 更新
Q6:KSP 与 kapt 的区别?为何推荐迁移到 KSP?
KSP(Kotlin Symbol Processing)是 Google 开发的 Kotlin 编译期注解处理器,作为 kapt 的替代方案:
- 性能:KSP 比 kapt 快 2~3 倍。kapt 需要先将 Kotlin 代码编译为 Java Stub(为了兼容 Javac 注解处理器),这一步骤非常耗时;KSP 直接解析 Kotlin 源码 AST,无中间产物
- 实现语言:kapt 底层是 Java 注解处理器(JSR 269),用 Java 编写处理器;KSP 提供原生 Kotlin API,处理器用 Kotlin 编写
- 内存占用:kapt 的 Java Stub 生成阶段占用大量内存;KSP 增量处理,内存开销更小
- 支持状态:Google 已明确 KSP 是长期方向,Room 2.5+、Moshi 1.14+ 已支持 KSP
- 迁移路径:将
kapt依赖替换为ksp,编译器实现从@AutoService(Processor::class)改为实现SymbolProcessor接口
七、ProGuard / R8 与 Jetpack 配置
7.1 Jetpack 组件的 ProGuard 规则
大部分 Jetpack 组件在 AAR 中内嵌了 proguard.txt(通过 consumerProguardFiles 声明),AGP 会自动应用这些规则。但以下组件需要手动添加:
# Lifecycle - 保持 LifecycleObserver 方法不被混淆 |
7.2 R8 完全模式
AGP 7.0+ 默认启用 R8 进行代码压缩、混淆和优化。在 gradle.properties 中开启 R8 完全模式:
android.enableR8.fullMode=true |
完全模式下 R8 会进行更激进的优化(方法内联、分支裁剪、类合并),但可能与某些反射调用冲突。如果遇到问题,可以通过 -keep 规则保留关键类。
Jetpack 组件大多已经过 R8 完全模式测试,但需要注意:
- Room 的
@Entity和@ColumnInfo注解类不应被混淆(AAR 自带规则会处理) - Paging 使用反射处理
LoadStateAdapter,需要保留相关类 - DataBinding 在运行时通过反射访问生成类,必须
-keep
八、Kotlin Multiplatform 与 Jetpack 的关系
8.1 现状与趋势
Google 正在将 Jetpack 逐步向 Kotlin Multiplatform (KMP) 迁移:
- **Room 2.7+**:已支持 KMP,可在 Android 和 iOS 上共享数据库层
- **DataStore 1.2+**:支持 KMP Preferences DataStore
- Lifecycle / ViewModel:已有
lifecycle-viewmodel-compose用于 Compose Multiplatform - Navigation:
navigation-compose逐步解耦 Fragment 依赖
8.2 跨平台共享策略
shared/ # KMP 共享模块 |
这种架构下,Room Database、Repository、UseCase、数据验证逻辑全部在 shared/commonMain 中实现,Android 和 iOS 两侧共享。UI 层各自用原生框架实现(Android 用 Jetpack Compose,iOS 用 SwiftUI)。







