AndroidのKotlin协程

2020-02-05  本文已影响0人  耑意儿
目录:
1. 协程Coroutines基础
2. 协程 - 超时与取消
3. 协程 - 结合挂起函数
Android小仙

参考资料:协程基础

1.协程Coroutines基础

1.1 GlobalScope.launch启动一个独立协程
1.2 runBlocking协程构建器构建一个协程
1.3 fun main() = runBlocking<Unit>{}将一个函数构建为协程函数
1.4 delay( 1000L ) 协程的挂起函数,只能在协程中使用。不会造成线程挂起
fun main(){
    GlobalScope.launch {
        // delay 是一个特殊的挂起函数,只能在协程中使用,它不会造成线程阻塞,但是会挂起协程,
        delay(1000)
        println("123")
    }
    println("Lisa Go")
    // Thread.sleep(3000)
    // 阻塞主线程3秒钟
    runBlocking {
        delay(3000)
        println("abc")
    }
    print("Lisa Stop")
}
/**
 * 调用协程构建器runBlocking函数,将主函数构建为协程,返回类型为Unit
 **/
fun main() = runBlocking<Unit>{

    // 需要保证的是,JVM在协程未执行完毕之前保持存活状态
    // 开启一个协程(子线程),子线程延迟1秒后打印123
    GlobalScope.launch {
        // delay 是一个特殊的挂起函数,只能在协程中使用,它不会造成线程阻塞,但是会挂起协程,
        delay(1000)
        println("123")
    }
    println("Lisa Go")
    // 此时,主线程已经是一个协程,不必再调runBlocking,直接调delay函数
    delay(3000)
    println("abc")
    print("Lisa Stop")
}
1.5 join函数将子协程加入主协程中
// 有趣的是,尽管subThread在最后才调用join方法,
// 但是在main执行1秒后先执行了333,而Lisa Finish在延迟2秒后才执行
fun main() = runBlocking {
    println("Lisa Go!")
    val subThread = GlobalScope.launch {
        delay(1000)
        println("333")
    }
    println("Lisa Finish")
    subThread.join()
}
1.6 结构化并发:在顶层协程的作用域内启动协程
// 通过在外部协程作用域内启动协程的方法,我们可以省去调用join的步骤
// 主线程会等到外部协程作用域内启动的所有协程执行完毕后才被销毁
fun main() = runBlocking {
//    GlobalScope.launch {
    launch {
        delay(1000)
        println("123")
    }
    println("Lisa Go")
}
1.7 作用域构建器:coroutineScope
// 这个构建器影响了一堆代码,abc不再是最先打印出来的
// coroutineScope创建了一个协程作用域,并且在所有已启动的子协程未执行完毕之前不会结束
// 这就意味着在coroutineScope之后的代码在该作用域内启动的所有子协程未执行完毕之前不会被执行到
fun main() = runBlocking { // this: CoroutineScope
    launch {
        delay(3000L)
        println("111")
    }

    launch {
        delay(4000L)
        println("222")
    }

    println("YoHoo")
    coroutineScope { // 创建一个协程作用域
        launch {
            delay(5000L)
            println("inner 111")
        }
        launch {
            delay(3000L)
            println("inner 222")
        }
        delay(1000L)
        println("inner abc")
    }

//    coroutineScope {
//        launch {
//            println("inner 111")
//        }
//        println("inner abc")
//    }
    launch {
        delay(3000L)
        println("333")
    }
    println("abc")
}
1.8 挂起函数
// 提取launch协程中的代码,抽出一个挂起函数,挂起函数被suspend修饰
fun main() = runBlocking {
    launch {
        suspendFun()
    }
    println("abc")
}
// 挂起函数只能被协程或者被另一个挂起函数调用!
suspend fun suspendFun(){
    delay(3000)
    println("123")
}
1.9 协程超轻量
// 存在打印遗漏,且打印顺序错乱
fun main2(){
    repeat(10000){ i ->
        GlobalScope.launch {
            println("123: "+i+" 次")
            delay(1000)
        }
    }
}
// 不会漏,而且按顺序走流程
fun main() = runBlocking{
    repeat(10000){ i ->
        launch {
            println("123: "+i+" 次")
            delay(1000)
        }
    }
}

2. 协程 - 超时与取消

2.1 超时限制
fun main() = runBlocking{
    try{
        withTimeout(1500){
            repeat(10){i ->
                launch {
                    delay(500)
                    println("yoyoo :"+i)
                }
            }
        }
    }catch (excep : TimeoutCancellationException) {
        println("catch exception")
    }finally {
        println("do finally")
    }
}
2.2 取消协程
fun main() = runBlocking {
    val job = launch {
        withTimeoutOrNull(3000){
            repeat(10){ i ->
                delay(500)
                println("111 "+i)
            }
        }
    }
    println("ready to cancel")
    delay(1200)
    job.cancel()
    println("after cancel")
}

3. 协程 - 结合挂起函数

上一篇下一篇

猜你喜欢

热点阅读