说明
- 可代替线程整异步
- 可控制,灵活 (控制优先级,内存占用等)
- 速度快 效率高
- 有数量上限
使用
- runBlocking 一般用于测试 不建议使用
- GlobalScope.launch 全局的 生命周期跟随application 不建议使用
- CoroutineScope(job) 用
基本使用
runBlocking {
Log.i("test_coroutine","我是一个runBlocking")
}
Log.i("test_coroutine","我在 runBlocking 协程外 且在 协程后")
GlobalScope.launch {
Log.i("test_coroutine","我是一个GlobalScope")
}
Log.i("test_coroutine","我在 GlobalScope 协程外 且在 协程后")
val job = Job()
val coroutineScope = CoroutineScope(job)
coroutineScope.launch {
Log.i("test_coroutine","我是一个coroutineScope")
}
Log.i("test_coroutine","我在 coroutineScope 协程外 且在 协程后")
结果
分析
runBlocking 阻塞主线程 执行了协程后 继续执行
GlobalScope.launch 不阻塞 继续执行主线程 后执行协程
coroutineScope.launch 不阻塞 继续执行主线程 后执行协程
- 增加延时,效果更明显 delay(1000)
runBlocking {
delay(1000)
Log.i("test_coroutine","我是一个runBlocking")
}
Log.i("test_coroutine","我在 runBlocking 协程外 且在 协程后")
GlobalScope.launch {
delay(1000)
Log.i("test_coroutine","我是一个GlobalScope")
}
Log.i("test_coroutine","我在 GlobalScope 协程外 且在 协程后")
val job = Job()
val coroutineScope = CoroutineScope(job)
coroutineScope.launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope")
}
Log.i("test_coroutine","我在 coroutineScope 协程外 且在 协程后")
结果
分析
runBlocking 阻塞主线程 执行了协程后 继续执行
GlobalScope.launch 协程内容最后执行
coroutineScope.launch 协程内容最后执行
1.1 协程里的挂起
val coroutineScope = CoroutineScope(Job())
val job = coroutineScope.launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope") //1
launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch") // 4
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch1") //5
}
Log.i("test_coroutine","我是一个coroutineScope1") // 2
Log.i("test_coroutine","我是一个coroutineScope2") // 3
}
结果
继续玩
val coroutineScope = CoroutineScope(Job())
val job = coroutineScope.launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope") //1
launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch") //3
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch1") //5
}
Log.i("test_coroutine","我是一个coroutineScope1") //2
delay(1500) //多了个delay
Log.i("test_coroutine","我是一个coroutineScope2") //4
}
结果
- join()
val coroutineScope = CoroutineScope(Job())
val job = coroutineScope.launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope") //1
val job1 = launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch") //3
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch1") //4
}
Log.i("test_coroutine","我是一个coroutineScope1") //2
job1.join()
delay(1500) //多了个delay
Log.i("test_coroutine","我是一个coroutineScope2") //5
}
结果: 执行的时候 job1加入了进来
- cancel()
val coroutineScope = CoroutineScope(Job())
val job = coroutineScope.launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope") //1
val job1 = launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch") //3
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch1") //不执行
}
Log.i("test_coroutine","我是一个coroutineScope1") //2
delay(1500) //多了个delay
Log.i("test_coroutine","我是一个coroutineScope2") //4
cancel()
}
结果 job 和 子job1都停了
- job1.cancel()
val coroutineScope = CoroutineScope(Job())
val job = coroutineScope.launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope")
val job1 = launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch")
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch1")
}
Log.i("test_coroutine","我是一个coroutineScope1")
delay(1500) //多了个delay
Log.i("test_coroutine","我是一个coroutineScope2")
job1.cancel()
Log.i("test_coroutine","我是一个coroutineScope3")
}
结果 job继续执行 job1停了
- job1.cancelAndJoin() 执行完之后 取消
val coroutineScope = CoroutineScope(Job())
val job = coroutineScope.launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope")
val job1 = launch {
var i = 0
while(i<10){
yield()
delay(500)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch>>${i++}")
}
}
Log.i("test_coroutine","我是一个coroutineScope1")
delay(1500) //多了个delay
Log.i("test_coroutine","我是一个coroutineScope2")
job1.join()
job1.cancel()
Log.i("test_coroutine","我是一个coroutineScope3")
}
结果 job1并没有被取消
- job1.cancelAndJoin()
val coroutineScope = CoroutineScope(Job())
val job = coroutineScope.launch {
delay(1000)
Log.i("test_coroutine","我是一个coroutineScope")
val job1 = launch {
var i = 0
while(i<10){
yield()
delay(500)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch>>${i++}")
}
}
Log.i("test_coroutine","我是一个coroutineScope1")
delay(1500) //多了个delay
Log.i("test_coroutine","我是一个coroutineScope2")
job1.cancelAndJoin()
Log.i("test_coroutine","我是一个coroutineScope3")
}
结果
-
ensureActive() 在协程不在 active 状态时会立即抛出异常。
-
yield() yield 会进行的第一个工作就是检查任务是否完成,如果 Job 已经完成的话,就会抛出 CancellationException 来结束协程。yield 应该在定时检查中最先被调用
-
async
val async = async {
var i = 0
while(i<10 && isActive){
delay(500)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch>>${i++}")
}
"完事啦"
}
Log.i("test_coroutine","我是一个coroutineScope1")
delay(1500) //多了个delay
Log.i("test_coroutine","我是一个coroutineScope2")
val result = async.await()
Log.i("test_coroutine","我是一个coroutineScope3 result>"+result)
Log.i("test_coroutine","我是一个coroutineScope4")
结果
- withTimeout
Log.i("test_coroutine","我是一个coroutineScope")
withTimeout(3000){
var i = 0
while(i<10 && isActive){
delay(500)
Log.i("test_coroutine","我是一个coroutineScope 里的 launch>>${i++}")
}
}
Log.i("test_coroutine","我是一个coroutineScope1")
delay(1500) //多了个delay
Log.i("test_coroutine","我是一个coroutineScope2")
结果 时间到后所在的协程也不继续执行了
Android中的协程
- MainScope
MainScope().launch {
}
- viewModelScope
implementation ‘androidx.lifecycle:lifecycle-viewmodel-android:2.8.0’
implementation ‘androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0’
implementation ‘androidx.lifecycle:lifecycle-common:2.8.0’
viewModelScope.launch {
}
- lifecycleScope
lifecycleScope.launch {
}
- rememberCoroutineScope() 可能会因为组件状态变化而移除此协程
@Composable
inline fun rememberCoroutineScope(
crossinline getContext: @DisallowComposableCalls () -> CoroutineContext =
{ EmptyCoroutineContext }
): CoroutineScope {
val composer = currentComposer
val wrapper = remember {
CompositionScopedCoroutineScopeCanceller(
createCompositionCoroutineScope(getContext(), composer)
)
}
return wrapper.coroutineScope
}
- currentRecomposeScope currentRecomposeScope 是一个在任何Composable函数中都能访问的成员
作用是使当前时刻组合无效,强制触发重组
val currentRecomposeScope: RecomposeScope
@ReadOnlyComposable
@OptIn(InternalComposeApi::class)
@Composable get() {
val scope = currentComposer.recomposeScope ?: error("no recompose scope found")
currentComposer.recordUsed(scope)
return scope
}
- supervisorScope 协程异常不影响其他协程
- coroutineScope 有异常所有携程都退出
本文参考 https://blog.csdn.net/Code1994/article/details/129448142