多重回调的回调地狱,就像是龟派气功。
饿了么资深Android工程师 张涛 如是说。
《领略Kotlin协程的力量》的学习笔记。
Kotlin的协程功能确实非常强大,类似Flutter的async/await使用。
什么是协程
-
进程 - 进程间切换要保存状态数据
- 单CPU 时间分片
- 多CPU 并行执行
-
线程 - 多线程切换,寄存器保存状态
- 线程阻塞
-
协程概念:通过提升CPU利用率,减少线程切换,进而提升CPU运行效率
-
协程的特点
- 可控制 - 协程能做到可被控制的发起子任务
- 轻量级 - 协程非常小,占用资源比线程还少
- 语法糖 - 使多任务或多线程切换不再使用回调方法
如何使用Kotlin协程
-
例子:第三方登录,多个顺序接口请求
-
不用协程:需要多重回调,陷入了回调地狱
-
使用协程: runBlocking - T 用于执行协程任务,通常用于启动最外层协程
-
launch:Job 协程内启动协程
fun setText(name: String) = launch(UI){ textView.text = name } -
async/await:Defered 成对出现,用于执行协程并获取返回值
suspend fun requestToken() = async(CommonPool){ return@async "curl http://www.example.com" }.await() -
suspend关键字 -
suspend修饰的函数(或lambda),只能被suspend修饰的函数(或lambda)调用// 编译前 suspend fun requestToken():String {...} // 编译后 Object requestToken(Continuation<String> c) {...} // Continuation接口 interface Continuation<in T> { val context: CoroutineContext fun resume(value: T) // 成功回调 fun resumeWithException(e: Throwable) // 失败回调 }
-
如何在现有的项目中引入协程
- 使用扩展方法,扩展已有方法
interface Service {
fun requestToken(): Call<Token>
}
suspend fun requestToken(): String =
serverInterface.requestToken().await()
- 改进I/O操作
fun save(textView: TextView, file: File) = runBlocking {
val text = textView.text.toString()
val deferred = async(CommonPool) {
file.appendText(text)
file.readText()
}
deferred.await()
}
- 引入协程时充分利用协程的特性
- 不要滥用协程