Kotlin

《Android Kotlin协程实战》

https://www.bilibili.com/video/BV1uo4y1y7ZF/?spm_id_from=333.999.0.0&vd_source=b5ef87e2f0a873011363576f8bdcba61
动脑学院 你能听懂的Kotlin协程课,跟老司机学,不用自己瞎折腾

###1.认识协程
协程是什么?协程基于线程,它是轻量级线程
异步任务和协程对比? 协程让异步逻辑同步化,杜绝回调地狱,协程的核心是函数或者一段程序能够被挂起,稍后再在挂起的位置恢复
协程的依赖: kotlinx-coroutines-core, kotlinx-coroutines-android

协程的挂起与恢复: suspend: 暂停执行当前协程,并保存所有的局部变量; resume:让已暂停的协程从其暂停处继续执行
挂起函数:suspend关键字修饰,只能在协程体内或其他挂起函数内调用
挂起和阻塞的区别? 主线程遇到挂起(如协程里调用了delay),先记下挂起点,然后该干嘛干嘛,如刷新UI,等挂起结束了,继续执行下面; 
            主线程如果阻塞了(如Thread.sleep),就啥事不干,一直等结束(阻塞就是线程被占用了,不能干其他事情)
            Choreographer: Skipped xxx frames! The application may be doing too much work on its main thead.
协程两部分:基础设施层和业务框架层
    基础设施层代码实例: val continuation=suspend {5}.createCoroutine(object : Continuation<Int> {override fun resumeWith(result: Result<Int>) {}}); continuation.resume(Unit)

协程调度器:
    Dispatchers.Main : Android上的主线程
    Dispatcher.IO: 非主线程
    Dispatcher.Default 非主线程,专为CPU密集型任务进行了优化

协程作用域:
    CoroutineScope: 会跟踪所有协程,同样可以取消它所启动的所有协程
    GlobalScope: 生命周期是process级别的,即使Activity或Fragment已经被销毁,协程仍然在执行
    MainScope:在Activity中使用,可以在onDestory中取消协程,cancel()方法,取消会报异常JobCancellationException: Job was cancelled;
    viewModelScope: 只能在ViewModel中使用,绑定ViewModel的生命周期
    lifecycleScope:只能在Activity或Fragment中使用,会绑定Activity和Fragment的生命周期

###2.协程的启动与取消
协程构建器:
    launch: 返回一个Job并且不附带任何结果
    async:返回一个Deferred,Deferred也是一个Job,可以使用await在一个延期的值上得到最终的结果
    等待上一个任务执行完:launch+join(); async+await()
    runBlocking {} 让我们的主线程变成一个协程
协程的启动模式:
    CoroutineStart.DEFAULT: 协程创建后,立即开始调度,在调度前协程如果被取消,其将直接进入取消响应的状态
    CoroutineStart.ATOMIC: 协程创建后,立即开始调度,协程执行到第一个挂起点之前不响应取消
    CoroutineStart.LAZY: 只有协程被需要时,包括主动调用协程的start,join或者await函数时才会开始调度,如果调度前就被取消,那么该协程将直接进入异常结束状态
    CoroutineStart.UNDISPATCHED: 协程创建后立即在当前函数调用栈中执行,直到遇到第一个真正挂起的点
如何指定协程上下文是Dispatchers.IO, 但是协程任务的执行仍然还在主线程? 执行协程启动模式为CoroutineStart.UNDISPATCHED 
协程作用域构建器:
    coroutineScope与runBlocking
    runBlocking是常规函数,coroutineScope是挂起函数
Job对象
    对于每一个创建的协程(通过launch或者async),会返回一个Job实例,负责管理协程的生命周期
    新创建New,活跃Active, 完成中Completing,已完成Completed,取消中Cancelling,已取消Cancelled,可以访问Job的属性:isActive,isCancelled和isCompleted
取消协程:
    取消作用域会取消它的子协程;被取消的子协程不会影响其余兄弟协程;协程通过抛出一个特殊的异常CancellationException来处理取消操作
CPU密集型任务取消
    isActive检查Job是否处于活跃状态;ensureActive(),如果job处于非活跃状态会立即抛出异常;yield函数如果取消会抛出CancellationException异常,还会尝试出让线程的执行权
    use函数:只能被实现了Closeable的对象使用,程序结束的时候会自动调用close方法,适合文件对象 
    不想协程被取消: withContext(NonCancellable) {} 
    超时任务:withTimeout(1000) {}; withTimeoutOrNull(1000) {}
    
###3.协程的异常处理
    协程上下文CoroutineContext是一组定义协程行为的元素
        Job:控制协程的生命周期
        CoroutineDispatcher: 向合适的线程分发任务
        CoroutineName: 协程的名称
        CoroutineExceptionHandler: 处理未被捕获的异常

    组合协程上下文: launch(Dispatchers.Default + CoroutineName("test")) {}  --重载了加号运算符
    协程上下文的继承:CoroutineScope协程作用域-》launch协程-》async子协程
            新创建的协程,它的CoroutineContext会包含一个全新的Job实例,剩下的元素从CoroutineContext的父类继承,该父类可能是另外一个协程或者创建该协程的CoroutineScope
            
    根协程异常传播:launch里抛出的异常:可以在launch协程里捕捉;async里抛出的异常,调用await后才能捕捉
    非根协程的异常:其他协程创建的协程中,产生的异常总是会被传播
    异常的传播特性:当一个协程由于异常运行失败时,它会传播这个异常并传递给它的父级,接下来父级会取消它自己的子级,取消它自己,将异常传播并传递给它的父级
    SupervisorJob: 一个子协程的运行失败不会影响到其他子协程,SupervisorJob不会传播异常给它的父级,它会让子协程自己处理异常
        CoroutineScope(SupervisorJob())
        作用域构建器supervisorScope {}, 在supervisorScope里创建的子协程里抛出异常,不会影响其他子协程;如果在supervisorScope作用域里抛出异常,所有子作业将会被全部取消
    异常的捕获:使用CoroutineExceptionHandler对协程的异常进行捕获
    取消与异常:取消(如joinAndCancel)会抛出CancellationException异常,当子协程被取消时,不会取消它的父协程
    异常聚合:CoroutineExceptionHandler { _, exception-> ${exception.suppressed.contentToString() --打印第二个异常}}

###4.Flow-异步流
    异步返回多个值: flow<Int> {  },
    flow: Flow构建器函数; flow{...} 构建快中代码可以挂起; 流使用emit函数发送值; 使用collect函数收集值
    Flow应用: Background Thread emit数据 -》Main Thread 去collect数据
    冷流: flow构建器中的代码直到流被收集的时候才运行
    流构建器: 
        flowOf()发射固定值的流
        使用asFlow扩展函数,可以将各种集合与序列转换成流: (1..3).asFlow().collect { value -> println(value) }
    流的上下文:flowOn操作符:用于更改流发射的上下文; launchIn指定在那个协程里收集数据
    流的取消: withTimeoutOrNull(2500) {}
    流的取消检测: 流构建器对每个发射值执行附加的ensureActive检测以进行取消
        如果想流可以被取消,需要明确指定cancellable:  (1..5).asFlow().cancellable().collect { value -> if (value == 3) cancel() }
    背压: 生产者生产效率大于消费者消费效率
        buffer() 并发运行流中发射元素的代码
        conflate() 合并发射项; collectLatest() 
    操作符: 转换操作符: map, transform; 限长操作符:take; 
         末端操作符: reduce ; 1到5平方并累加 (1..5).asFlow().map{ it*it }.reduce{ a,b->a+b }
    组合多个流: zip
    展平流: flatMapConcat连接模式, flatMapMerge合并模式, flatMapLatest最新展平模式
    流的异常: 收集的时候处理异常: 如check(value <= 1) {} ; 发射的时候抛出异常,使用catch函数捕捉
    流的完成: onCompletion

    
    
        
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容