Android Jetpack:官方架构组件套件
认识 Android Jetpack:官方架构组件套件
Jetpack 是一套库、工具和指南,旨在帮助开发者更轻松地编写高质量应用。它涵盖了从 UI、数据管理到后台任务、导航等常见需求,让你避免重复造轮子,专注于应用的核心逻辑。Jetpack 组件大多与 Kotlin 协程、生命周期感知等现代开发模式深度集成,是 Android 官方推荐的开发方式。
为什么你应该使用 Jetpack
- 减少样板代码:自动管理生命周期、处理配置变更(如屏幕旋转),避免内存泄漏。
- 加速开发:提供可组合的模块化组件,按需集成,无需从头实现。
- 现代开发实践:原生支持 Kotlin、声明式 UI (Compose)、响应式数据流。
- 一致性与向后兼容:API 设计统一,多数组件向下兼容至 API Level 14。
核心组件分类
Jetpack 组件分为四大类,你可以根据应用需求自由组合。
| 类别 | 代表组件 | 主要作用 |
|---|---|---|
| 架构 (Architecture) | ViewModel, LiveData, Room, DataStore, Navigation | 应用架构、数据持久化、页面导航 |
| 界面 (UI) | Compose, ViewBinding, Palette, Emoji, RecyclerView | 构建响应式界面、处理 UI 交互 |
| 行为 (Behavior) | Permissions, Notifications, Media3, DownloadManager | 用户交互、媒体播放、后台通知 |
| 基础 (Foundation) | AppCompat, Android KTX, Test | 向后兼容、Kotlin 扩展、测试支持 |
本教程将重点剖析最常用的架构组件,它们是构建健壮应用的基础。
架构组件实战指南
1. ViewModel:生命周期感知的数据持有者
ViewModel 负责为界面准备和管理数据,并在配置变更(如屏幕旋转)后存活。它将数据与 UI 控制器(Activity/Fragment)解耦,避免内存泄漏。
class MyViewModel : ViewModel() {
private val _userName = MutableLiveData<String>()
val userName: LiveData<String> = _userName
fun loadUser() {
// 模拟异步加载
_userName.value = "Alice"
}
}
在 Activity 中获取 ViewModel:
class MainActivity : AppCompatActivity() {
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 观察数据变化
viewModel.userName.observe(this) { name ->
// 更新 UI
}
}
}
2. LiveData:可观察的数据容器
LiveData 是一种持有可被观察的数据类。它与生命周期绑定,只在 UI 组件处于活跃状态(STARTED 或 RESUMED)时更新界面,自动防止内存泄漏和已销毁界面的更新。
// 在 ViewModel 中
val productList: LiveData<List<Product>> = repository.getProducts()
// 在 Activity 中
viewModel.productList.observe(this) { products ->
// 更新 RecyclerView
}
进阶用法:结合 Transformations.map 和 MediatorLiveData 进行数据转换与合并。
3. Room:SQLite 对象映射库
Room 在 SQLite 数据库上提供了一个抽象层,通过注解即可定义实体、DAO 和数据库,编译时自动生成实现代码。它支持 Flow 和 LiveData 的响应式查询。
实体定义:
@Entity
data class User(
@PrimaryKey val uid: Int,
@ColumnInfo(name = "full_name") val fullName: String
)
数据访问对象 (DAO):
@Dao
interface UserDao {
@Query("SELECT * FROM user")
fun getAll(): Flow<List<User>>
@Insert
suspend fun insert(user: User)
}
数据库构建:
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
使用时,建议以单例形式提供数据库实例,防止资源浪费。
4. DataStore:替代 SharedPreferences 的数据存储
DataStore 提供两种方式:Preferences DataStore 和 Proto DataStore。它使用 Kotlin 协程和 Flow 异步存取键值对或类型化数据,避免了 SharedPreferences 的主线程阻塞风险。
// 创建
val Context.dataStore by preferencesDataStore(name = "settings")
// 读取
val themeFlow: Flow<String> = context.dataStore.data
.map { preferences ->
preferences[THEME_KEY] ?: "light"
}
// 写入
suspend fun setTheme(theme: String) {
context.dataStore.edit { preferences ->
preferences[THEME_KEY] = theme
}
}
5. Navigation:简化导航与参数传递
Navigation 组件通过导航图(XML 或 Compose 路由)可视化地管理应用内导航,自动处理 Fragment 事务和返回栈。还支持类型安全的参数传递和深度链接。
导航图示例(res/navigation/nav_graph.xml):
<navigation ... startDestination="@id/homeFragment">
<fragment android:id="@+id/homeFragment" ...>
<action android:id="@+id/action_to_detail"
app:destination="@id/detailFragment" />
</fragment>
<fragment android:id="@+id/detailFragment" ...>
<argument android:name="itemId" app:argType="integer" />
</fragment>
</navigation>
在代码中导航:
findNavController().navigate(R.id.action_to_detail, bundleOf("itemId" to 123))
6. WorkManager:可靠的后台任务调度
适用于必须完成的延迟、可推迟任务,即使应用退出或设备重启也能运行。例如上传日志、定期同步数据。WorkManager 内部选择合适的执行方案(JobScheduler、AlarmManager 等)。
val uploadWork = OneTimeWorkRequestBuilder<UploadWorker>()
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
.build()
WorkManager.getInstance(context).enqueue(uploadWork)
UploadWorker 需要继承 Worker 并实现 doWork():
class UploadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
// 执行上传逻辑
return Result.success()
}
}
7. Paging 3:高效的分页加载
Paging 库帮助你按需加载和显示大型数据集,降低网络和内存开销。它与 RecyclerView 原生集成,自动处理请求下一页、重试等逻辑。
核心类包括 PagingSource(定义数据来源)、Pager(配置)和 PagingDataAdapter(展示)。
class ExamplePagingSource : PagingSource<Int, Item>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Item> {
val position = params.key ?: 0
val response = api.getItems(position, params.loadSize)
return LoadResult.Page(
data = response.items,
prevKey = if (position == 0) null else position - 1,
nextKey = if (response.items.isEmpty()) null else position + 1
)
}
}
在 ViewModel 中收集数据:
val items: Flow<PagingData<Item>> = Pager(PagingConfig(pageSize = 20)) {
ExamplePagingSource()
}.flow.cachedIn(viewModelScope)
Adapter 只需继承 PagingDataAdapter 即可获得分页更新。
最佳实践与组合使用
在实际开发中,这些组件往往协同工作:
- ViewModel 持有 LiveData 或 Flow 的状态,并通过 DataStore 或 Room 获取数据。
- Room 返回
Flow或PagingSource,直接对应 UI 的响应式更新或分页列表。 - Navigation 负责页面跳转并传递参数,ViewModel 通过 SavedStateHandle 获取导航参数。
- WorkManager 在后台同步 Room 数据库与远程服务器。
下一步学习
- 深入学习 Jetpack Compose(声明式 UI 框架)。
- 尝试 Hilt 依赖注入库,简化组件供给。
- 阅读官方太阳计划文档了解最新组件。
从今天起,新建一个项目,用 ViewModel + DataStore 替代传统的配置存储,你将立刻体会到 Jetpack 的便利与优雅。