协程是什么
协程并不是 Kotlin 提出来的新概念,其他的一些编程语言,例如:Go、Python 等都可以在语言层面上实现协程,甚至是 Java,也可以通过使用扩展库来间接地支持协程。
在使用协程之前,我们需要在 build.gradle 文件中增加对 Kotlin 协程的依赖:
buildscript {
...
// 👇 coroutines版本
ext.kotlin_coroutines = '1.3.1'
...
}
Module 下的 build.gradle :
// 👇 依赖协程核心库
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines"
// 👇 依赖当前平台所对应的平台库
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines"
协程最简单的使用方法,通过一个 launch 函数实现线程切换的功能
val coroutineScope = CoroutineScope(Dispatchers.Default)
coroutineScope.launch(Dispatchers.IO) {
val image = getImage(imageId)
launch(Dispatch.Main) {
avatarIv.setImageBitmap(image)
}
}
使用withcontext
coroutineScope.launch(Dispatchers.Main) { // 👈 在 UI 线程开始
val image = withContext(Dispatchers.IO) { // 👈 切换到 IO 线程,并在执行完成后切回 UI 线程
getImage(imageId) // 👈 将会运行在 IO 线程
}
avatarIv.setImageBitmap(image) // 👈 回到 UI 线程更新 UI
}
也可以这么写
launch(Dispachers.Main) { // 👈 在 UI 线程开始
val image = getImage(imageId)
avatarIv.setImageBitmap(image) // 👈 执行结束后,自动切换回 UI 线程
}
// 👇
suspend fun getImage(imageId: Int) = withContext(Dispatchers.IO) {
...
}
常用的 Dispatchers ,有以下三种:
- Dispatchers.Main:Android 中的主线程
- Dispatchers.IO:针对磁盘和网络 IO 进行了优化,适合 IO 密集型的任务,比如:读写文件,操作数据库以及网络请求
- Dispatchers.Default:适合 CPU 密集型的任务,比如计算