线程框架。【更方便】
协程就是launch里面的代码。
挂起协程。
launch创建的协程在执行到某一个suspend函数挂起函数的时候,这个协程会被suspend(被挂起)
从当前线程挂起。
这个协程从正在执行它的线程上脱离了。不是这个协程停下来了而是协程所在的线程从这行代码开始不再运行这个协程了。
线程和协程分2波走了。
协程的代码块在线程里到了suspend函数的时候突然执行完了、返回了。然后线程就做它自己的事情了。比如这个线程是后台线程,那么这个线程就nothing to do.该回收回收,该利用利用。如果这个线程是main thread,则线程会回去继续工作。
图中的伪代码是启动了一个执行在主线程的协程。它实质上会在主线程post()一个new task:
handler.post{val todo = suspendToDo()...
}
这个task就是协程代码。当这个协程被挂起的时候,实质上就是post()的这个task提前结束了。
然后主线程继续刷新ui。
协程还没用执行完,剩下的代码:协程。
函数的代码在到达suspend函数的时候被掐断了,它会从这个挂起函数开始继续往下执行【是在指定的线程(挂起函数指定的)】
launch(Dispatchers.Main){...val todo=suspendToDo()....
}suspend fun suspendToDo(){withContext(Dispatchers.IO){....}
}
例如上面就是函数内部的withContext()所指定的io线程。
例如上面伪代码中,协程原来是在main thread中运行的,切回来就是在挂起函数执行完成之后,协程会再post()一个task,让剩下的代码继续回到主线程去执行。这是因为Dispatchers调度器可以指定协程执行的线程还可以在suspend挂起函数之后自动再切回来。【设置特殊的调度器可以让挂起函数执行完后不再切回来】
所以,挂起:
协程在执行到有supend标记的函数的时候会被挂起,挂起和开启一个协程一样,就是切个线程。只不过挂起函数在执行完毕之后协程会自动的重新切回它原先的那个线程。挂起就是一个稍后会被自动切回来的线程切换。
挂起之后是需要恢复的,恢复这个功能是协程的。挂起函数不在协程里被调用,那么这个恢复的功能就没法实现了。
如果单纯的定义一个suspend标识的函数然后在协程里面去调用它是没效果的。因为它不知道往哪里切。
对于自定义的挂起函数,例如withContext()有调度器。
协程的被挂起并不是发生在外部这个挂起函数被调用的时候,而是里面的挂起函数被调用的时候,例如常见的withContext()。【withcotext()也不是真的切线程的点,而是其内部的底层代码】
所以supend关键字并不启到协程挂起/切换线程的作用。真要挂起协程还需要在挂起函数里去调用另一个挂起函数【需要是协程自带的、内部实现了协程挂起代码的。或它的内部直接或者间接调用了某一个挂起函数,让它去真正的挂起。】
提醒。【函数的创建者对函数的调用者的提醒】
“我”是一个耗时的函数,我被我的创建者用挂起的方式放到了后台运行,所以要在协程里调用“我”。
它让我们的主线程不卡。通过挂起函数这种形式把耗时task切线程的这个工作交给了函数的创建者而不是调用者。
调用者只会收到一个提醒:你只需要把我放在一个协程里调用。
怎么custom a supend function?
1.什么时候自定义?
2.怎么写?
学习扔物线大佬的suspend总结。
本文发布于:2024-02-02 12:05:28,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170684672943682.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |