Kotlin 的协程用力瞥一眼,webrtc音视频开发

本文探讨Kotlin协程的优势及基本使用,通过实例展示了如何在网络请求和UI更新中运用协程,强调了协程在简化异步编程中的作用。同时,文章提到了协程在Android开发中的应用,包括使用GlobalScope和CoroutineScope的注意事项,以及如何配置和启动协程。此外,还预告了后续将深入讲解协程的'非阻塞式挂起'概念。
摘要由CSDN通过智能技术生成

这里并不会比较 RxJava 和协程哪个好,或者讨论谁取代谁的问题,我这里只给出一个建议,你最好都去了解下,因为协程和 Rx 的设计思想本来就不同。

下面的例子是使用协程进行网络请求获取用户信息并显示到 UI 控件上:

🏝️
launch({
val user = api.getUser() // 👈 网络请求(IO 线程)
nameTv.text = user.name // 👈 更新 UI(主线程)
})

这里只是展示了一个代码片段,launch 并不是一个顶层函数,它必须在一个对象中使用,我们之后再讲,这里只关心它内部业务逻辑的写法。

launch 函数加上实现在 {} 中具体的逻辑,就构成了一个协程。

通常我们做网络请求,要不就传一个 callback,要不就是在 IO 线程里进行阻塞式的同步调用,而在这段代码中,上下两个语句分别工作在两个线程里,但写法上看起来和普通的单线程代码一样。

这里的 api.getUser 是一个挂起函数,所以能够保证 nameTv.text 的正确赋值,这就涉及到了协程中最著名的「非阻塞式挂起」。这个名词看起来不是那么容易理解,我们后续的文章会专门对这个概念进行讲解。现在先把这个概念放下,只需要记住协程就是这样写的就行了。

这种「用同步的方式写异步的代码」看起来很方便吧,那么我们来看看协程具体好在哪。

协程好在哪

开始之前

在讲之前,我们需要先了解一下「闭包」这个概念,调用 Kotlin 协程中的 API,经常会用到闭包写法。

其实闭包并不是 Kotlin 中的新概念,在 Java 8 中就已经支持。

我们先以 Thread

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

浏览器打开:qq.cn.hn/FTe 开源分享

为例,来看看什么是闭包:

🏝️
// 创建一个 Thread 的完整写法
Thread(object : Runnable {
override fun run() {

}
})

// 满足 SAM,先简化为
Thread({

})

// 使用闭包,再简化为
Thread {

}

形如 Thread {...} 这样的结构中 {} 就是一个闭包。

在 Kotlin 中有这样一个语法糖:当函数的最后一个参数是 lambda 表达式时,可以将 lambda 写在括号外。这就是它的闭包原则。

在这里需要一个类型为 Runnable 的参数,而 Runnable 是一个接口,且只定义了一个函数 run,这种情况满足了 Kotlin 的 SAM,可以转换成传递一个 lambda 表达式(第二段),因为是最后一个参数,根据闭包原则我们就可以直接写成 Thread {...}(第三段) 的形式。

对于上文所使用的 launch 函数,可以通过闭包来进行简化 :

🏝️
launch {

}

基本使用

前面提到,launch 函数不是顶层函数,是不能直接用的,可以使用下面三种方法来创建协程:

🏝️
// 方法一,使用 runBlocking 顶层函数
runBlocking {
getImage(imageId)
}

// 方法二,使用 GlobalScope 单例对象
// 👇 可以直接调用 launch 开启协程
GlobalScope.launch {
getImage(imageId)
}

// 方法三,自行通过 CoroutineContext 创建一个 CoroutineScope 对象
// 👇 需要一个类型为 CoroutineContext 的参数
val coroutineScope = CoroutineScope(context)
coroutineScope.launch {
getImage(imageId)
}

  • 方法一通常适用于单元测试的场景,而业务开发中不会用到这种方法,因为它是线程阻塞的。

  • 方法二和使用 runBlocking 的区别在于不会阻塞线程。但在 Android 开发中同样不推荐这种用法,因为它的生命周期会和 app 一致,且不能取消(什么是协程的取消后面的文章会讲)。

  • 方法三是比较推荐的使用方法,我们可以通过 context 参数去管理和控制协程的生命周期(这里的 context 和 Android 里的不是一个东西,是一个更通用的概念,会有一个 Android 平台的封装来配合使用)。

关于 CoroutineScopeCoroutineContext 的更多内容后面的文章再讲。

协程最常用的功能是并发,而并发的典型场景就是多线程。可以使用 Dispatchers.IO 参数把任务切到 IO 线程执行:

🏝️
coroutineScope.launch(Dispatchers.IO) {

}

也可以使用 Dispatchers.Main 参数切换到主线程:

🏝️
coroutineScope.launch(Dispatchers.Main) {

}

所以在「协程是什么」一节中讲到的异步请求的例子完整写出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值