react 前端框架如何驱动企业数字化转型与创新发展
2559
2022-12-12
kotlin之协程的理解与使用详解
前言
为什么在kotlin要使用协程呢,这好比去了重庆不吃火锅一样的道理。协程的概念并不陌生,在python也有提及。任何事务的作用大多是对于所依赖的环境相应而生的,协程对于kotlin这门语言也不例外。协程的优点,总的来说有如下几点:轻量级,占用更少的系统资源; 更高的执行效率; 挂起函数较于实现Runnable或Callable接口更加方便可控; kotlin.coroutine 核心库的支持,让编写异步代码更加简单。当然在一些不适应它的用法下以上优势也会成为劣势。
1.协程定义
协程定义:kotlin官方基于JVM的线程实现的一个并发任务处理框架,封装的线程api
使用方便,不使用回调实现线程切换,使用同步方式写出异步代码
所有的耗时任务保证一定放在后台执行挂起
函数执行完毕之后,协程会把它切换到原先的线程的线程。
2.协程的基本用法
常规函数中一般都有:call and return,协程在此之外添加了suspend和resume.
suspend 用于暂停执行的当前协程,并保存所有的局部变量
resume 用于已暂停的协程中暂停出恢复
supend(挂起函数)是什么,有什么意义
suspend,对协程的挂起并没有实际作用,其实只是一个提醒,函数创建者对函数的调用者的提醒,提醒调用者我是需要耗时操作,需要用挂起的方式,在协程中使用.
需要注意的是挂起函数只能在挂起函数或者协程作用域中使用,为什么挂起函数需要在协程作用域中使用?因为普通函数没有suspend和resume这两个特性,所以必须要在协程的作用中使用。
意义:
语法层面:作为一个标记和提醒。通过报错来提醒调用者和编译器,这是一个耗时函数,需要放在后台执行。
编译器层面:辅助 Kotlin 编译器来把代码转换成 JVM 的字节码。
怎么自定义suspend函数?
什么时候定义?
需要耗时操作的时候,需要定义,例如io耗时操作(请求网络);获取数据库数据;一些等待一会需要的操作;列http://表排除,json解析等;
怎么写suspend函数,给函数前加上suspend 关键字,把内容用withContext包起来
suspend fun testSuspendfun(){
withContext(Dispatchers.IO){
}
}
协程如何确保主线程安全
Dispatchers.Main 调用程序在android的主线程中
Dispatchers.IO 适合主线程之外的执行磁盘或者网络io操作,例如文件的读取与写入,任何的网络请求
Dispatcher.Default 适合主线程之外的,cpu的操作,例如json数据的解析,以及列表的排序,
协程的挂起本质:本质就是切线程,完成之后只不过可以自动切回来
协程挂起就是切个线程,在挂起函数执行完毕之后,协程会自动的重新切回它原先的线程,也就是稍后会被切回来的线程切换。切回来就是resume,恢复功能是协程,所以suspend函数需要在另一个suspend函数或者协程中调用。「非阻塞式挂起」阻塞的方式写出了非阻塞的方式。
3.协程的创建以及取消
//创建一个协程
Val scope = CoroutineScope(Dispatchers.Main+Job())
通过Job获取协程的生命周期
scope.launch{
}
其他耗时请求,例如从数据库中获取数据
scope.async {
}
在KTX库为某些生命周期提供自己的CoroutineScope,例如ViewModel中viewModelScope,Lifecycle有lifecycleScope
协程的启动,launch 启动新协程而不将结果返回给调用方
//创建之后,不管后续
launch(){
}
async 启动一个新协程,并通过deferred的await方法暂停函数
//返回deferred 对象
val deferred async{
}
deferred.await()
协程的结构化并发,取消协程
协程的结构化并发,可以让协程非常便于管理。例如在关闭activity中要取消协程。如果是在线程中,取消所有的线程比较复杂。
取消父协程以及父里面的子协程
val scope = CoroutineScope(Dispatchers.Main+ Job())
scope.launch {
val job = launch {
val job1 = launch {
}
}
job.cancel()
}
scope.cancel()
取消子协程某一个,每一个协程都会返回一个job对象,通过调用job的cancle,可以去取消单个的协程的。
val scope = CoroutineScope(Dispatchers.Main+ Job())
scope.launch {
val job = launch {
val job1 = launch {
}
}
job.cancel()
}
scope.cancel()
4.协程中异常处理
在协程内部中捕获异常
val scope = CoroutineScope(Dispatchers.Mhttp://ain+ Job())
scope.launch {
try {
}catch (e:Exception){
}
}
5.协程的优势
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~