Android kotlin协程

说明

  • 可代替线程整异步
  • 可控制,灵活 (控制优先级,内存占用等)
  • 速度快 效率高
  • 有数量上限

使用

  • 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值