Bootstrap

Android开发实战班 - 应用架构 之 Kotlin 协程基础

Kotlin 协程(Coroutines)是 Kotlin 提供的一种轻量级线程,用于简化异步编程和并发任务处理。相比传统的线程,协程更高效、更易读,并且更易于维护。协程在 Android 开发中广泛应用,尤其是在处理网络请求、数据库操作、UI 异步更新等场景中。本章节将介绍 Kotlin 协程的基本概念、核心组件、生命周期管理以及在 Android 开发中的应用。

12.1 Kotlin 协程简介

  • 什么是协程:

    • 协程是一种轻量级的线程,用于简化异步编程和并发任务处理。
    • 协程可以挂起(suspend)和恢复(resume),而不阻塞线程。
  • 协程的优势:

    • 轻量级: 协程比线程更轻量,可以创建大量的协程而不会消耗太多资源。
    • 可读性高: 协程代码更简洁,易于理解和使用。
    • 灵活性强: 协程可以轻松地在不同线程之间切换。
    • 内存效率: 协程的内存占用比线程低,可以更高效地使用内存。

12.2 协程的基本概念

  • 协程作用域 (CoroutineScope):

    • 协程作用域用于管理协程的生命周期。
    • 常见的协程作用域有 GlobalScope, lifecycleScope, viewModelScope 等。
    • 使用 CoroutineScope 可以确保协程在不需要时自动取消,避免内存泄漏。
    val scope = CoroutineScope(Dispatchers.Main)
    scope.launch {
        // 协程代码
    }
    
  • 协程构建器 (Coroutine Builders):

    • 协程构建器用于启动协程。
    • 常见的协程构建器有 launch, async, runBlocking 等。
    // 使用 launch 构建器启动协程
    val job = scope.launch {
        // 异步任务
    }
    
    // 使用 async 构建器启动协程并获取结果
    val deferred = scope.async {
        // 异步任务
        return@async "Result"
    }
    val result = deferred.await()
    
  • 挂起函数 (Suspend Functions):

    • 挂起函数是使用 suspend 关键字声明的函数,可以在协程中挂起和恢复。
    • 挂起函数只能在协程或另一个挂起函数中调用。
    suspend fun fetchData(): String {
        // 模拟网络请求
        delay(1000)
        return "Data"
    }
    
  • 调度器 (Dispatchers):

    • 调度器用于指定协程运行的线程。
    • 常见的调度器有 Dispatchers.Main, Dispatchers.IO, Dispatchers.Default 等。
    // 在主线程中运行协程
    scope.launch(Dispatchers.Main) {
        // UI 操作
    }
    
    // 在 IO 线程中运行协程
    scope.launch(Dispatchers.IO) {
        // 网络请求或数据库操作
    }
    

12.3 协程的核心组件

  • Job:

    • Job 是协程的句柄,用于控制协程的生命周期。
    • 可以使用 job.cancel() 取消协程,使用 job.join() 等待协程完成。
    val job = scope.launch {
        // 异步任务
    }
    
    // 取消协程
    job.cancel()
    
    // 等待协程完成
    job.join()
    
  • Deferred:

    • DeferredJob 的子接口,用于表示异步计算的结果。
    • 可以使用 await() 方法获取异步计算的结果。
    val deferred = scope.async {
        // 异步计算
        return@async 42
    }
    
    val result = deferred.await()
    
  • SupervisorJob:

    • SupervisorJob 用于管理多个子协程的生命周期。
    • 当一个子协程失败时,不会影响其他子协程。
    val supervisor = SupervisorJob()
    val scope = CoroutineScope(Dispatchers.Main + supervisor)
    
    scope.launch {
        // 子协程 1
    }
    
    scope.launch {
        // 子协程 2
    }
    
    // 如果一个子协程失败,不会影响另一个子协程
    

12.4 协程的生命周期管理

  • 自动取消:

    • 使用 lifecycleScopeviewModelScope 可以自动管理协程的生命周期。
    • 当 Activity 或 Fragment 销毁时,协程会自动取消,避免内存泄漏。
    class MyActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            // 使用 lifecycleScope 启动协程
            lifecycleScope.launch {
                // 异步任务
            }
        }
    }
    
  • 手动取消:

    • 可以使用 Jobcancel() 方法手动取消协程。
    val job = scope.launch {
        // 异步任务
    }
    
    // 取消协程
    job.cancel()
    

12.5 协程在 Android 开发中的应用

  • 网络请求:

    • 使用协程可以简化网络请求的代码,提高代码可读性。
    suspend fun fetchData() {
        withContext(Dispatchers.IO) {
            // 网络请求
        }
    }
    
    lifecycleScope.launch {
        val data = fetchData()
        // 更新 UI
    }
    
  • 数据库操作:

    • 使用协程可以简化数据库操作的代码,提高代码效率。
    suspend fun getUsers(): List<User> {
        return withContext(Dispatchers.IO) {
            // 数据库查询
            return@withContext userDao.getAllUsers()
        }
    }
    
    lifecycleScope.launch {
        val users = getUsers()
        // 更新 UI
    }
    
  • UI 异步更新:

    • 使用协程可以简化 UI 异步更新的代码,提高代码简洁性。
    lifecycleScope.launch {
        // 异步任务
        withContext(Dispatchers.Main) {
            // 更新 UI
        }
    }
    

12.6 实战案例

  1. 案例一:使用协程实现网络请求

    • 创建一个 ViewModel,使用协程进行网络请求。
    • 在 Activity 中观察 ViewModel 的 LiveData,更新 UI。
  2. 案例二:使用协程实现数据库操作

    • 创建一个 ViewModel,使用协程进行数据库操作。
    • 在 Jetpack Compose Composable 中观察 ViewModel 的 Flow,更新 UI。

12.7 课后作业

  1. 任务一:使用协程实现网络请求

    • 创建一个 ViewModel,使用协程进行网络请求。
    • 在 Activity 中观察 ViewModel 的 LiveData,更新 UI。
  2. 任务二:使用协程实现数据库操作

    • 创建一个 ViewModel,使用协程进行数据库操作。
    • 在 Jetpack Compose Composable 中观察 ViewModel 的 Flow,更新 UI。
  3. 任务三:使用协程实现图片下载

    • 创建一个 ViewModel,使用协程下载图片。
    • 在 Activity 中观察 ViewModel 的 LiveData,更新 ImageView。

通过本章节的学习,学员将能够掌握 Kotlin 协程的基本概念、核心组件和生命周期管理,并能够使用协程简化异步编程和并发任务处理,提高代码效率和可读性。

;