Kotlin中协程的使用

官方介绍协程

协程定义

协程定义:kotlin官方基于JVM的线程实现的一个并发任务处理框架,封装的线程api

  • 使用方便,不使用回调实现线程切换,使用同步方式写出异步代码
  • 所有的耗时任务保证一定放在后台执行
  • 挂起函数执行完毕之后,协程会把它切换到原先的线程的线程。

协程的基本用法

常规函数中一般都有:call and return,协程在此之外添加了suspend和resume.

  • suspend 用于暂停执行的当前协程,并保存所有的局部变量
  • resume 用于已暂停的协程中暂停出恢复
supend(挂起函数)是什么,有什么意义

suspend,对协程的挂起并没有实际作用,其实只是一个提醒,函数创建者对函数的调用者的提醒,提醒调用者我是需要耗时操作,需要用挂起的方式,在协程中使用.

  • 需要注意的是挂起函数只能在挂起函数或者协程作用域中使用,为什么挂起函数需要在协程作用域中使用?因为普通函数没有suspend和resume这两个特性,所以必须要在协程的作用中使用。

意义:

  • 语法层面:作为一个标记和提醒。通过报错来提醒调用者和编译器,这是一个耗时函数,需要放在后台执行。

  • 编译器层面:辅助 Kotlin 编译器来把代码转换成 JVM 的字节码。

怎么自定义suspend函数?
  • 什么时候定义?

需要耗时操作的时候,需要定义,例如io耗时操作(请求网络);获取数据库数据;一些等待一会需要的操作;列表排除,json解析等;

  • 怎么写suspend函数

给函数前加上suspend 关键字,把内容用withContext包起来

suspend fun testSuspendfun(){
      withContext(Dispatchers.IO){

      }
  }
协程如何确保主线程安全
  • Dispatchers.Main 调用程序在Android的主线程中
  • Dispatchers.IO 适合主线程之外的执行磁盘或者网络io操作,例如文件的读取与写入,任何的网络请求
  • Dispatcher.Default 适合主线程之外的,cpu的操作,例如json数据的解析,以及列表的排序,
协程的挂起本质
  • 本质就是切线程,完成之后只不过可以自动切回来

协程挂起就是切个线程,在挂起函数执行完毕之后,协程会自动的重新切回它原先的线程,也就是稍后会被切回来的线程切换。切回来就是resume,恢复功能是协程,所以suspend函数需要在另一个suspend函数或者协程中调用.

  • 什么是协程的「非阻塞式挂起」

阻塞的方式写出了非阻塞的方式

协程的创建以及取消

//创建一个协程

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()

协程中异常处理

  • 在协程内部中捕获异常
val scope = CoroutineScope(Dispatchers.Main+ Job())
        scope.launch {
            try {
                
            }catch (e:Exception){
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值