kotlin 协程的用法

协程是什么?

协程作用域(CoroutineScope)是什么?

在 Android 中如何用协程(尤其是生命周期绑定)?

我们来从底层原理 → 语法机制 → Android 实践 三层讲清楚。


🧩 一、协程是什么?

一句话总结:

协程是一种轻量级的线程(更准确说是线程上的可挂起任务)

能在一个线程中挂起、恢复执行,让异步代码像同步一样写。


✅ 举个最通俗的例子:

不用协程(传统写法):
kotlin 复制代码
Thread {
    val data = loadFromNetwork()
    runOnUiThread {
        showData(data)
    }
}.start()
用协程:
kotlin 复制代码
lifecycleScope.launch {
    val data = withContext(Dispatchers.IO) {
        loadFromNetwork()
    }
    showData(data)
}

👉 逻辑完全一样,但写法更直观,没有回调地狱。

协程可以在同一线程中**挂起(suspend)**执行异步任务,待任务完成后自动恢复。


🧠 二、协程的本质

协程 ≠ 线程。

协程是 运行在某个线程上的任务调度单元 ,由协程调度器(Dispatcher)管理。

对比项 线程(Thread) 协程(Coroutine)
创建成本 高(1MB 栈空间) 低(几 KB)
切换成本 系统级上下文切换 用户态调度(轻量)
异步写法 回调或线程池 同步结构(挂起)
生命周期 操作系统管理 Kotlin 代码层管理

⚙️ 三、协程作用域(CoroutineScope)

作用域(Scope) 决定了:

  1. 协程在哪个上下文(线程)中运行;
  2. 协程的生命周期;
  3. 异常取消策略。

✅ 1️⃣ 常见作用域类型

作用域 用途 生命周期
GlobalScope 全局协程,不推荐 应用进程
lifecycleScope Android Activity / Fragment 绑定 随生命周期结束自动取消
viewModelScope Android ViewModel 绑定 ViewModel 销毁时取消
CoroutineScope 自定义作用域 由开发者控制取消

✅ 2️⃣ 示例:自定义作用域

kotlin 复制代码
class MyRepository {

    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())

    fun fetchData() {
        scope.launch {
            val data = loadDataFromNetwork()
            println(data)
        }
    }

    fun clear() {
        scope.cancel() // 主动取消
    }
}

🧩 四、在 Android 中如何使用协程

✅ 1️⃣ Activity / Fragment 中使用

绑定生命周期 → 用 lifecycleScope

kotlin 复制代码
lifecycleScope.launch {
    val user = withContext(Dispatchers.IO) { getUser() }
    updateUI(user)
}

当 Activity 销毁时,lifecycleScope 会自动取消协程,避免内存泄漏。


✅ 2️⃣ ViewModel 中使用

绑定 viewModelScope,协程自动随 ViewModel 销毁而取消:

kotlin 复制代码
class UserViewModel : ViewModel() {

    fun loadUser() {
        viewModelScope.launch {
            val user = withContext(Dispatchers.IO) { getUserFromDb() }
            _userLiveData.value = user
        }
    }
}

👉 这是最标准的 Android 架构写法。


✅ 3️⃣ Repository 层

通常是挂起函数 + IO 调度:

kotlin 复制代码
class UserRepository {
    suspend fun getUser(): User {
        return withContext(Dispatchers.IO) {
            apiService.getUser()
        }
    }
}

调用端(ViewModel):

kotlin 复制代码
viewModelScope.launch {
    val user = repository.getUser()
}

✅ 4️⃣ 常用调度器(Dispatchers)

调度器 用途 对应线程池
Dispatchers.Main UI 操作 主线程
Dispatchers.IO 网络 / 文件 / 数据库 IO 线程池
Dispatchers.Default CPU 密集计算 默认线程池
Dispatchers.Unconfined 不固定线程 测试或特殊情况

🧠 五、协程关键语法

1️⃣ launch

启动一个协程,不返回结果(类似 fire-and-forget):

kotlin 复制代码
launch {
    doSomething()
}

2️⃣ async / await

启动并返回结果:

kotlin 复制代码
val result = async { getData() }
println(result.await())

3️⃣ withContext

切换线程并返回结果:

kotlin 复制代码
val data = withContext(Dispatchers.IO) { loadFromDb() }

4️⃣ suspend

标记挂起函数(可在协程中调用):

kotlin 复制代码
suspend fun getData(): String {
    delay(1000) // 模拟耗时操作
    return "OK"
}

🧩 六、协程异常与取消

✅ 异常捕获

kotlin 复制代码
viewModelScope.launch {
    try {
        val data = repository.getData()
    } catch (e: Exception) {
        Log.e("TAG", "error: $e")
    }
}

✅ 取消协程

kotlin 复制代码
val job = launch {
    repeat(1000) {
        delay(100)
        println("Working $it")
    }
}

delay(500)
job.cancel() // 协程被取消

🔥 七、面试速答总结

Kotlin 协程是基于挂起函数的轻量级异步方案,能让异步代码以同步形式书写。

协程运行在作用域中,作用域决定协程的生命周期和调度线程。

在 Android 中:

  • Activity / Fragment 用 lifecycleScope
  • ViewModel 用 viewModelScope
  • 数据层使用挂起函数 + IO 调度
    协程底层通过 Continuation 对象恢复挂起点,实现非阻塞线程的异步执行。

相关推荐
DokiDoki之父14 小时前
边写软件边学kotlin(一):Kotlin语法初认识:
android·开发语言·kotlin
fundroid2 天前
Kotlin 泛型进阶:in、out 与 reified 实战
android·开发语言·kotlin
JMchen1232 天前
现代Android图像处理管道:从CameraX到OpenGL的60fps实时滤镜架构
android·图像处理·架构·kotlin·android studio·opengl·camerax
JMchen1234 天前
Android CameraX深度解析:从Camera1到CameraX的相机架构演进
android·java·数码相机·架构·kotlin·移动开发·android-studio
倔强的石头1064 天前
【Linux指南】进程控制系列(五)实战 —— 微型 Shell 命令行解释器实现
linux·运维·kotlin
Hz4534 天前
Android Jetpack核心组件协同实战:Navigation 3.X+Lifecycle+Flow+Hilt的架构革新
android·kotlin
JMchen1234 天前
Android音频编码原理与实践:从AAC到Opus,深入解析音频编码技术与移动端实现
android·经验分享·学习·kotlin·android studio·音视频·aac
JMchen1235 天前
Android音频处理全解析:从3A算法到空间音频,打造专业级音频体验
android·经验分享·算法·kotlin·android studio·音视频
瓦特what?5 天前
C++编程防坑指南(小说版)
android·c++·kotlin
一招定胜负5 天前
卷积神经网络提取人脸五个特征点
人工智能·cnn·kotlin