Jorgen's blog Jorgen's blog
首页
  • 平台架构
  • 混合式开发记录
  • 推送服务
  • 数据分析
  • 实时调度
  • 架构思想

    • 分布式
  • 编程框架工具

    • 编程语言
    • 框架
    • 开发工具
  • 数据存储与处理

    • 数据库
    • 大数据
  • 消息、缓存与搜索

    • 消息队列
    • 搜索与日志分析
  • 前端与跨端开发

    • 前端技术
    • Android
  • 系统与运维

    • 操作系统
    • 容器化与 DevOps
  • 物联网与安全

    • 通信协议
    • 安全
    • 云平台
newland
  • 关于我
  • 终身学习
  • 关于时间的感悟
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

jorgen

Love it, make mistakes, learn, keep grinding.
首页
  • 平台架构
  • 混合式开发记录
  • 推送服务
  • 数据分析
  • 实时调度
  • 架构思想

    • 分布式
  • 编程框架工具

    • 编程语言
    • 框架
    • 开发工具
  • 数据存储与处理

    • 数据库
    • 大数据
  • 消息、缓存与搜索

    • 消息队列
    • 搜索与日志分析
  • 前端与跨端开发

    • 前端技术
    • Android
  • 系统与运维

    • 操作系统
    • 容器化与 DevOps
  • 物联网与安全

    • 通信协议
    • 安全
    • 云平台
newland
  • 关于我
  • 终身学习
  • 关于时间的感悟
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Capacitor浅析
  • ADB调试
  • mlkit
  • face detection
  • Android中的Kotlin协程:告别回调地狱
  • Android性能优化实践与技巧
  • Android Jetpack Compose入门:构建现代UI的全新方式
  • Android Jetpack Compose入门与实践 - 构建现代Android UI
  • Android Jetpack Compose入门指南 - 构建现代UI的全新方式
  • Android Jetpack与架构组件-构建现代化应用
  • Android Jetpack架构组件:ViewModel与LiveData实战指南
  • Android Jetpack组件:构建现代Android应用的核心利器
  • Android Jetpack组件详解:构建现代化应用的核心
  • Android数据绑定与MVVM架构-构建现代化应用
  • Android架构组件:构建现代化应用的基石
  • Android架构组件与Jetpack-构建现代化应用的基石
    • 前言
    • 什么是Android架构组件与Jetpack?
    • 核心架构组件
      • 1. ViewModel 🧠
      • 2. LiveData 🔁
      • 3. Room 🏠
      • 4. Data Binding 📝
    • 其他重要的Jetpack组件
      • 1. Navigation 🧭
      • 2. WorkManager 🛠️
      • 3. Paging 📄
    • 架构模式:MVVM
    • 实践:构建一个简单的用户列表应用
      • 1. 定义数据模型
      • 2. 创建Repository
      • 3. 创建ViewModel
      • 4. 创建UI
      • 5. 在Activity中绑定
    • 常见问题与解决方案
      • 1. ViewModel的生命周期
      • 2. LiveData与StateFlow的选择
      • 3. 处理复杂的导航
    • 个人建议
    • 结语
  • Android架构组件与Jetpack-构建现代化应用的基础
  • Android架构设计之MVVM模式实战指南
  • 拥抱未来:Android Jetpack Compose入门指南
  • Android权限管理完全指南-从基础到实践
  • Android测试指南-从单元测试到UI测试的实践之路
  • Android依赖注入实战:从Dagger到Hilt的进化之路
  • Android网络编程完全指南-从HTTP到Retrofit的实践之路
  • Android数据持久化完全指南-从SharedPreferences到Room数据库
  • Android多线程与并发处理完全指南-从Thread到协程的进阶之路
  • Android应用打包与发布全流程指南-从签名到上架的实战之路
  • Android安全完全指南-从基础防护到高级加密的实战之路
  • android
Jorgen
2023-11-15
目录

Android架构组件与Jetpack-构建现代化应用的基石

# 前言

作为一名Android开发者,你是否曾经遇到过这样的困境:项目代码越来越难以维护,Activity/Fragment中的逻辑臃肿不堪,测试难以进行,或者团队中的每个人都在使用不同的架构模式?🤔

在我早期的Android开发经历中,这些问题几乎成了家常便饭。直到有一天我的代码复杂度达到了临界点,连我自己都看不懂自己写的逻辑了。幸运的是,Google推出了Android架构组件和Jetpack套件,为我们提供了一套完整的解决方案,帮助我们构建高质量、可维护、可测试的Android应用。

今天,我想和大家一起探索Android架构组件与Jetpack的魅力,看看它们如何成为我们构建现代化应用的基石。

# 什么是Android架构组件与Jetpack?

Android Jetpack是一套库、工具和指南,帮助开发者更轻松地编写高质量的Android应用。而架构组件则是Jetpack中的一个重要组成部分,专门用于帮助开发者设计健壮、可测试且可维护的应用。

提示

Jetpack的主要目标是:

  • 加速开发:提供Kotlin友好的API,减少样板代码
  • 统一UI:确保在不同设备上有一致的用户体验
  • 推荐最佳实践:遵循最新的Android设计规范
  • 兼容性:向后兼容,支持旧版本Android系统
  • 推动现代实践:鼓励使用Kotlin协程、LiveData等现代编程模式

# 核心架构组件

Android架构组件主要包括以下几个部分:

# 1. ViewModel 🧠

ViewModel以生命周期感知的方式保存和管理UI相关的数据。它允许数据在配置更改(如屏幕旋转)时存活,从而避免不必要的资源重建。

class UserProfileViewModel : ViewModel() {
    private val userId: String = ...
    
    // 使用LiveData来暴露数据
    val user: LiveData<User> = UserRepository().getUser(userId)
}
1
2
3
4
5
6

ViewModel的主要优势:

  • 生命周期感知:自动处理配置更改,无需手动处理
  • 可测试性:可以轻松地单独测试ViewModel逻辑
  • 数据持久化:在配置更改时保持数据状态

# 2. LiveData 🔁

LiveData是一种可观察的数据持有者类,遵循观察者模式。与常规的可观察类不同,LiveData是生命周期感知的,这意味着它只会更新处于活跃生命周期状态的应用组件观察者。

// 在ViewModel中定义LiveData
val userName: LiveData<String> = MutableLiveData()

// 在Activity/Fragment中观察
viewModel.userName.observe(this, { newName ->
    textView.text = newName
})
1
2
3
4
5
6
7

LiveData的特点:

  • 生命周期感知:自动管理订阅和取消订阅
  • 数据更新:当数据变化时通知观察者
  • 防止内存泄漏:自动清理不再需要的观察者
  • 始终最新:新观察者会立即接收最新数据

# 3. Room 🏠

Room是一个持久性库,它在SQLite之上提供了一个抽象层,让用户能够在更少的代码中更轻松地访问数据库。

// 定义实体
@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "name") val name: String
)

// 定义DAO
@Dao
interface UserDao {
    @Query("SELECT * FROM users")
    fun getAllUsers(): LiveData<List<User>>
}

// 定义数据库
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Room的优势:

  • 编译时验证:在编译时检查SQL查询
  • 简化数据库迁移:提供简单的迁移机制
  • 与LiveData集成:可以轻松地将数据库查询暴露为LiveData流

# 4. Data Binding 📝

Data Binding库允许您将UI组件绑定到数据源,使用声明式格式而非编程式,从而简化UI代码。

<!-- 布局文件中使用Data Binding -->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="user"
            type="com.example.User" />
    </data>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{user.name}" />
</layout>
1
2
3
4
5
6
7
8
9
10
11
12

在Activity/Fragment中使用:

val binding: ActivityProfileBinding = DataBindingUtil.setContentView(this, R.layout.activity_profile)
binding.user = viewModel.user
1
2

Data Binding的好处:

  • 减少样板代码:减少findViewById和手动设置UI的代码
  • 提高可读性:将UI逻辑与业务逻辑分离
  • 双向数据绑定:支持从UI到数据的反向绑定

# 其他重要的Jetpack组件

除了架构组件外,Jetpack还提供了许多其他有用的组件:

# 1. Navigation 🧭

Navigation组件用于在应用中实现导航,它简化了Fragment之间的导航处理,并提供了一致的后退行为。

// 在导航图中定义目的地
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/homeFragment">

    <fragment
        android:id="@+id/homeFragment"
        android:name="com.example.HomeFragment"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home">
        <action
            android:id="@+id/action_homeFragment_to_profileFragment"
            app:destination="@id/profileFragment" />
    </fragment>
</navigation>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 2. WorkManager 🛠️

WorkManager用于调度可保证会运行的后台工作,即使应用程序退出或设备重启。

// 定义Worker
class UploadWorker(appContext: Context, workerParams: WorkerParameters)
    : CoroutineWorker(appContext, workerParams) {
    
    override suspend fun doWork(): Result {
        // 执行上传任务
        uploadFiles()
        return Result.success()
    }
}

// 调度工作
val uploadWorkRequest: WorkRequest = OneTimeWorkRequestBuilder<UploadWorker>()
    .build()
WorkManager.getInstance(context).enqueue(uploadWorkRequest)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 3. Paging 📄

Paging库帮助开发者从数据源加载和显示分页数据,同时最大限度地减少网络和数据库资源的使用。

// 创建PagingSource
class UserPagingSource(private val apiService: ApiService) : PagingSource<Int, User>() {
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, User> {
        // 加载分页数据
        return try {
            val page = params.key ?: 1
            val users = apiService.getUsers(page)
            LoadResult.Page(
                data = users,
                prevKey = if (page == 1) null else page - 1,
                nextKey = if (users.isEmpty()) null else page + 1
            )
        } catch (e: Exception) {
            LoadResult.Error(e)
        }
    }
}

// 创建PagingFlow
val pager = Pager(
    config = PagingConfig(pageSize = 20),
    pagingSourceFactory = { UserPaging(apiService) }
).flow.cachedIn(viewModelScope)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 架构模式:MVVM

虽然Jetpack组件可以单独使用,但它们通常与MVVM(Model-View-ViewModel)架构模式一起使用,以实现最佳效果。

MVVM架构图

在MVVM架构中:

  • Model:表示数据和业务逻辑,通常包括Repository和数据库
  • View:表示UI层,如Activity、Fragment和XML布局
  • ViewModel:作为View和Model之间的桥梁,处理UI相关的逻辑

THEOREM

MVVM架构的核心原则:

  • 单一职责:每个组件都有明确的职责
  • 数据驱动:UI通过数据变化更新,而不是直接调用方法
  • 可测试性:业务逻辑与UI分离,便于单元测试

# 实践:构建一个简单的用户列表应用

让我们通过一个简单的例子,看看如何使用Jetpack组件构建一个用户列表应用。

# 1. 定义数据模型

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "name") val name: String,
    @ColumnInfo(name = "email") val email: String
)
1
2
3
4
5
6

# 2. 创建Repository

class UserRepository(private val userDao: UserDao) {
    fun getUsers(): LiveData<List<User>> = userDao.getAllUsers()
    
    suspend fun refreshUsers() {
        // 从网络获取最新数据并存入数据库
        val users = apiService.getUsers()
        userDao.insertAll(users)
    }
}
1
2
3
4
5
6
7
8
9

# 3. 创建ViewModel

class UserListViewModel(private val repository: UserRepository) : ViewModel() {
    val users: LiveData<List<User>> = repository.getUsers()
    
    fun refreshUsers() {
        viewModelScope.launch {
            repository.refreshUsers()
        }
    }
}
1
2
3
4
5
6
7
8
9

# 4. 创建UI

<!-- activity_user_list.xml -->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewModel"
            type="com.example.UserListViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".UserListActivity">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:listData="@{viewModel.users}" />

        <Button
            android:id="@+id/refreshButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="刷新"
            android:onClick="@{() -> viewModel.refreshUsers()}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 5. 在Activity中绑定

class UserListActivity : AppCompatActivity() {
    private lateinit var binding: ActivityUserListBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        binding = DataBindingUtil.setContentView(this, R.layout.activity_user_list)
        
        val database = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "database-name"
        ).build()
        
        val repository = UserRepository(database.userDao())
        val viewModel = ViewModelProvider(this).get(UserListViewModel::class.java)
        
        binding.viewModel = viewModel
        binding.lifecycleOwner = this
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 常见问题与解决方案

# 1. ViewModel的生命周期

问题:ViewModel在什么情况下会被销毁?

解答:ViewModel会在其关联的Activity或Fragment被销毁时被销毁,除非配置更改(如屏幕旋转)。在配置更改时,ViewModel会被保留。

# 2. LiveData与StateFlow的选择

问题:我应该使用LiveData还是StateFlow?

解答:

  • LiveData:

    • 生命周期感知,无需手动管理订阅
    • 与Android组件集成良好
    • 适合简单的UI状态管理
  • StateFlow:

    • 基于Kotlin协程,更灵活
    • 支持背压和取消
    • 适合复杂的流处理和跨平台共享

# 3. 处理复杂的导航

问题:如何处理复杂的导航逻辑,如深度链接和参数传递?

解答:使用Navigation组件的安全参数功能,通过类型安全的方式传递参数:

// 在导航图中定义参数
<fragment
    android:id="@+id/detailFragment"
    android:name="com.example.DetailFragment"
    android:label="fragment_detail">
    <argument
        android:name="userId"
        app:argType="integer" />
</fragment>

// 导航时传递参数
val action = HomeFragmentDirections.actionHomeFragmentToDetailFragment(userId = 123)
findNavController().navigate(action)
1
2
3
4
5
6
7
8
9
10
11
12
13

# 个人建议

在我使用Jetpack组件的几年经验中,我总结了几点建议:

  1. 从小处着手:不要试图一次性重构整个应用。可以先在一个新功能中尝试使用Jetpack组件,逐步扩展。

  2. 遵循最佳实践:Google提供了许多关于架构的最佳实践,如"单一数据源"原则。遵循这些原则可以避免常见的架构问题。

  3. 保持简洁:不要过度使用Jetpack组件。如果简单的解决方案就能解决问题,就不要引入不必要的复杂性。

  4. 持续学习:Jetpack组件在不断更新,如Hilt(依赖注入)和Paging 3.0等新组件不断推出。保持学习可以帮助你使用最新的工具。

  5. 编写测试:Jetpack组件使编写测试变得更加容易。充分利用这一点,确保你的应用质量。

# 结语

Android架构组件与Jetpack为我们提供了一套强大的工具,帮助我们构建高质量、可维护、可测试的Android应用。从ViewModel到LiveData,从Room到Navigation,这些组件不仅简化了开发过程,还遵循了现代软件开发的最佳实践。

"优秀的架构不是关于技术,而是关于解决问题的清晰思维。"

我相信,掌握这些工具和概念,将使你在Android开发的道路上走得更远。无论你是初学者还是有经验的开发者,Jetpack都能帮助你构建更好的应用。

期待在未来的文章中,与大家分享更多关于Android开发的精彩内容!如果你有任何问题或建议,欢迎在评论区留言交流。👋

记住,好的架构不是一蹴而就的,它是一个持续演进的过程。保持学习,不断改进,你的应用会变得越来越好!

#Android#Jetpack#架构组件#MVVM
上次更新: 2026/01/28, 10:42:53
Android架构组件:构建现代化应用的基石
Android架构组件与Jetpack-构建现代化应用的基础

← Android架构组件:构建现代化应用的基石 Android架构组件与Jetpack-构建现代化应用的基础→

最近更新
01
LLM
01-30
02
intro
01-30
03
intro
01-30
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Jorgen | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式