第2章:环境搭建——在Android/Kotlin项目中引入协程依赖

好,咱们直接进入正题。这一章我带你搞定协程的环境搭建。说实话,很多新手卡在这一步——依赖配不对,Gradle报错,第一个协程跑不起来。别急,我踩过的坑都帮你填平了。

2.1 为什么需要手动引入协程依赖?

你可能觉得奇怪:Kotlin不是自带协程吗?为什么还要加依赖?

嗯,这里要澄清一下。Kotlin标准库只提供了最基础的协程原语(比如 suspend 关键字、Continuation 接口)。真正好用的东西——launchasyncDispatchersFlow——都在 kotlinx.coroutines 这个官方库里面。说白了,标准库是发动机,kotlinx.coroutines 是方向盘和座椅,你得自己装。

核心依赖关系:

  • kotlin-stdlib → 基础协程支持(自动包含)
  • kotlinx-coroutines-core → 协程核心库(必须手动添加)
  • kotlinx-coroutines-android → Android专用调度器(Android项目必加)

2.2 在Android项目中配置Gradle

我个人习惯把协程版本号定义在项目级的 build.gradle 里,这样所有模块统一管理。你想想看,如果每个模块写死版本号,升级的时候得改多少个地方?

第一步:项目级 build.gradle(或 build.gradle.kts)

// 项目级 build.gradle
buildscript {
    ext {
        // 我建议用最新稳定版,目前是 1.7.3
        // 你可以去 GitHub 搜 kotlinx.coroutines 看最新版本
        kotlin_coroutines_version = '1.7.3'
    }
}

第二步:模块级 build.gradle

dependencies {
    // 核心库 —— 所有协程功能的基础
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
    
    // Android专用库 —— 提供 Main 调度器
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
    
    // 可选:如果你用 Lifecycle 组件,可以加这个
    // implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
}

⚠️ 避坑指南:

我曾经遇到过一个问题:只加了 coroutines-core 没加 coroutines-android,结果在 Android 主线程调用 Dispatchers.Main 直接崩溃。因为 Dispatchers.Main 的实现是在 coroutines-android 里提供的。记住:Android项目两个都要加。

2.3 第一个协程示例——Hello Coroutine!

环境搭好了,咱们跑一个最简单的例子。我习惯在 Activity 的 onCreate 里直接写,方便看效果。

import kotlinx.coroutines.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 第一个协程
        CoroutineScope(Dispatchers.Main).launch {
            println("协程启动!当前线程:${Thread.currentThread().name}")
            
            // 模拟网络请求
            val result = fetchData()
            
            println("拿到结果:$result")
        }
    }
    
    // suspend 函数 —— 协程的基石
    private suspend fun fetchData(): String {
        // delay 是协程版的 Thread.sleep,不会阻塞线程
        delay(1000L)  // 模拟1秒延迟
        return "Hello Coroutine!"
    }
}

运行一下,你会看到控制台输出:

协程启动!当前线程:main
// 等待1秒后...
拿到结果:Hello Coroutine!

注意看,虽然 delay 了1秒,但主线程并没有卡住。这就是协程的魔力——它挂起了自己,把线程让出来做别的事。你想想看,如果用 Thread.sleep(1000),整个界面会卡死1秒,用户体验直接崩掉。

2.4 理解协程的三个核心组件

刚才的例子虽然简单,但包含了协程的三大要素。我帮你拆解一下:

组件 作用 示例中的体现
CoroutineScope 协程的作用域,管理协程的生命周期 CoroutineScope(Dispatchers.Main)
Dispatcher 指定协程在哪个线程执行 Dispatchers.Main(主线程)
suspend 函数 可挂起的函数,协程的构建块 fetchData()

💡 个人经验:

刚开始学的时候,你可能会纠结「什么时候用 Dispatchers.Main,什么时候用 Dispatchers.IO」。我的经验是:UI操作用 Main,网络请求和数据库操作用 IO。记住这个原则,90%的场景都不会错。

2.5 常见问题与避坑

我在教学和项目中遇到过不少同学踩坑,这里集中说一下:

  1. Gradle 同步失败:检查一下你的 Kotlin 版本和协程版本是否兼容。比如 Kotlin 1.8.0 搭配协程 1.7.3 没问题,但 Kotlin 1.6.0 配协程 1.7.3 就会报错。版本对照表可以去 kotlinx.coroutines GitHub 看。

  2. 找不到 Dispatchers.Main:原因我前面说了——没加 kotlinx-coroutines-android 依赖。加上就好了。

  3. 协程不执行:检查一下你的 CoroutineScope 是否被 GC 回收了。我曾经在 Fragment 里创建了 scope,但 Fragment 销毁后 scope 也跟着没了,协程自然就不跑了。解决方案是用 viewModelScopelifecycleScope,它们会跟随生命周期自动管理。

2.6 小结

这一章我们做了三件事:

  • 配好了协程的 Gradle 依赖
  • 跑通了第一个协程示例
  • 理解了 Scope、Dispatcher、suspend 这三个核心概念

下一章我会带你深入 launchasync 的区别,以及如何用协程优雅地处理并发任务。嗯,到时候你会觉得「原来多线程可以这么简单」。

对了,如果你在配置过程中遇到任何问题,欢迎在评论区留言。我每天都会看,尽量当天回复。