美文网首页kotlin相关专题
Kotlin中协程的使用

Kotlin中协程的使用

作者: fengyongge | 来源:发表于2020-07-16 14:53 被阅读0次

    官方介绍协程

    协程定义

    协程定义: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){
                }
            }
    

    相关文章

      网友评论

        本文标题:Kotlin中协程的使用

        本文链接:https://www.haomeiwen.com/subject/ujvphktx.html