Android Kotlin学习(七)- 协程

本文介绍了Kotlin中协程的基础用法,包括如何创建协程、使用suspend关键字挂起函数、Dispatchers来指定线程执行,以及如何利用withContext和async/await进行并发操作。此外,还展示了如何取消协程的执行。


协程之前一直没有了解过,今天大致梳理下简单的使用方法,个人认为协程相比较JAVA简化了多线程调用,逻辑更清晰

创建协程

介绍常用的方法,这里可以通过Job去管理和控制协程的生命周期,launch 函数创建一个新的协程,并在指定的线程上运行它

        var job = Job()
        var scope = CoroutineScope(job)
        scope.launch {
        }

suspend

suspend是协程的一个关键词,代码执行到 suspend 函数的时候会挂起,离开当前运行的线程,在指定的线程开始执行,执行完毕后再恢复协程代码块,并且自动帮我们把线程再切回来

suspend fun doSome(data:String):String{
}

Dispatchers

Dispatchers 用来将协程限制在一个特定的线程执行

Dispatchers.Main        主线程执行程序
Dispatchers.Default    IO线程上运行程序
Dispatchers.IO            CPU 密集型工作进行了优化

withContext

withContext函数控制代码运行的线程,当代码块中的代码全部执行完之后,会将最后一行的执行结果作为withContext()函数的返回值返回

示例

fun launchText(){
    Log.i(TAG,"other start==="+Thread.currentThread().id)
    //创建一个协程
    var job = Job()
    var scope = CoroutineScope(job)
    //在主线程调用
    scope.launch(Dispatchers.Main) {
        Log.i(TAG,"START==="+Thread.currentThread().id)
        //suspend 是一个耗时函数,其它线程运行
        var res = doSome("World")
        //继续回到主线程去执行
        Log.i(TAG,"end===${res}"+Thread.currentThread().id)
    }
    Log.i(TAG,"other end==="+Thread.currentThread().id)
}
suspend fun doSome(data:String):String{
    var res = withContext(Dispatchers.IO){
        for (i in 0 until 10){
            Log.i(TAG,"withContext =${data} ${i} "+Thread.currentThread().id)
        }
        "Hello"+data
    }
    return res
}

打印日志

6498-6498/com.kotlin.demo I/TestActivity: other start===2
6498-6498/com.kotlin.demo I/TestActivity: other end===2
6498-6498/com.kotlin.demo I/TestActivity: START===2
6498-6526/com.kotlin.demo I/TestActivity: withContext =World 0 497
6498-6526/com.kotlin.demo I/TestActivity: withContext =World 1 497
6498-6526/com.kotlin.demo I/TestActivity: withContext =World 2 497
6498-6526/com.kotlin.demo I/TestActivity: withContext =World 3 497
6498-6526/com.kotlin.demo I/TestActivity: withContext =World 4 497
6498-6526/com.kotlin.demo I/TestActivity: withContext =World 5 497
6498-6526/com.kotlin.demo I/TestActivity: withContext =World 6 497
6498-6526/com.kotlin.demo I/TestActivity: withContext =World 7 497
6498-6526/com.kotlin.demo I/TestActivity: withContext =World 8 497
6498-6526/com.kotlin.demo I/TestActivity: withContext =World 9 497
6498-6498/com.kotlin.demo I/TestActivity: end===HelloWorld2

async和await

如果需要再一个协程里面开启多个耗时操作,并且需要同步进行,然后汇总结果,这个时候就需要使用async,async会启动一个新的协程,可以使用await 的函数在稍后返回结果

fun launchText1(){
    Log.i(TAG,"other start==="+Thread.currentThread().id)
    var job = Job()
    var scope = CoroutineScope(job)
    scope.launch(Dispatchers.Main) {
       // 开启两个耗时协程
        Log.i(TAG,"START==="+Thread.currentThread().id)
        var do1 = async {
            doSome1("World1")
        }
        var do2 = async {
            doSome2("World2")
        }
        //等待耗时协程结束后开始进行接下来的操作
        Log.i(TAG,"end===${do1.await()} ${do2.await()}"+Thread.currentThread().id)
    }
    Log.i(TAG,"other end==="+Thread.currentThread().id)
}

suspend fun doSome1(data:String):String{
    var res = withContext(Dispatchers.IO){
        for (i in 0 until 10){
            delay(1000)
            Log.i(TAG,"doSome1 =${data} ${i} "+Thread.currentThread().id)
        }
        "Hello"+data
    }
    return res
}

suspend fun doSome2(data:String):String{
    var res = withContext(Dispatchers.IO){
        for (i in 0 until 10){
            delay(1000)
            Log.i(TAG,"doSome2 =${data} ${i} "+Thread.currentThread().id)
        }
        "Hello"+data
    }
    return res
}

日志

6659-6659/com.kotlin.demo I/TestActivity: other start===2
6659-6659/com.kotlin.demo I/TestActivity: other end===2
6659-6659/com.kotlin.demo I/TestActivity: START===2
6659-6686/com.kotlin.demo I/TestActivity: doSome1 =World1 0 507
6659-6685/com.kotlin.demo I/TestActivity: doSome2 =World2 0 506
6659-6686/com.kotlin.demo I/TestActivity: doSome1 =World1 1 507
6659-6685/com.kotlin.demo I/TestActivity: doSome2 =World2 1 506
6659-6685/com.kotlin.demo I/TestActivity: doSome1 =World1 2 506
6659-6688/com.kotlin.demo I/TestActivity: doSome2 =World2 2 509
6659-6688/com.kotlin.demo I/TestActivity: doSome1 =World1 3 509
6659-6685/com.kotlin.demo I/TestActivity: doSome2 =World2 3 506
6659-6685/com.kotlin.demo I/TestActivity: doSome1 =World1 4 506
6659-6688/com.kotlin.demo I/TestActivity: doSome2 =World2 4 509
6659-6687/com.kotlin.demo I/TestActivity: doSome1 =World1 5 508
6659-6685/com.kotlin.demo I/TestActivity: doSome2 =World2 5 506
6659-6685/com.kotlin.demo I/TestActivity: doSome1 =World1 6 506
6659-6687/com.kotlin.demo I/TestActivity: doSome2 =World2 6 508
6659-6687/com.kotlin.demo I/TestActivity: doSome1 =World1 7 508
6659-6685/com.kotlin.demo I/TestActivity: doSome2 =World2 7 506
6659-6685/com.kotlin.demo I/TestActivity: doSome1 =World1 8 506
6659-6687/com.kotlin.demo I/TestActivity: doSome2 =World2 8 508
6659-6687/com.kotlin.demo I/TestActivity: doSome1 =World1 9 508
6659-6688/com.kotlin.demo I/TestActivity: doSome2 =World2 9 509
6659-6659/com.kotlin.demo I/TestActivity: end===HelloWorld1 HelloWorld22

协程取消

有创建肯定有取消,协程取消使用cancel函数,如上述例子添加计时取消逻辑

 fun launchText1(){
        Log.i(TAG,"other start==="+Thread.currentThread().id)
        var job = Job()
        var scope = CoroutineScope(job)
        scope.launch(Dispatchers.Main) {
            Log.i(TAG,"START==="+Thread.currentThread().id)
            var job1 = GlobalScope.launch(Dispatchers.Main) {
                var do1 = async {
                    doSome1("World1")
                }
                var do2 = async {
                    doSome2("World2")
                }
                Log.i(TAG,"end===${do1.await()} ${do2.await()} "+Thread.currentThread().id)
            }
            for (i in 0 until 5){
                delay(1000)
                if (i == 4){
                    Log.i(TAG,"cancel==========="+Thread.currentThread().id)
                    job1.cancel()
                }
            }
        }
        Log.i(TAG,"other end==="+Thread.currentThread().id)
    }

日志

7225-7225/com.kotlin.demo I/TestActivity: other start===2
7225-7225/com.kotlin.demo I/TestActivity: other end===2
7225-7225/com.kotlin.demo I/TestActivity: START===2
7225-7262/com.kotlin.demo I/TestActivity: doSome2 =World2 0 548
7225-7261/com.kotlin.demo I/TestActivity: doSome1 =World1 0 547
7225-7263/com.kotlin.demo I/TestActivity: doSome2 =World2 1 549
7225-7261/com.kotlin.demo I/TestActivity: doSome1 =World1 1 547
7225-7261/com.kotlin.demo I/TestActivity: doSome2 =World2 2 547
7225-7262/com.kotlin.demo I/TestActivity: doSome1 =World1 2 548
7225-7262/com.kotlin.demo I/TestActivity: doSome2 =World2 3 548
7225-7261/com.kotlin.demo I/TestActivity: doSome1 =World1 3 547
7225-7225/com.kotlin.demo I/TestActivity: cancel===========2
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菠萝加点糖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值