Android Kotlin学习(七)- 协程
协程之前一直没有了解过,今天大致梳理下简单的使用方法,个人认为协程相比较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
本文介绍了Kotlin中协程的基础用法,包括如何创建协程、使用suspend关键字挂起函数、Dispatchers来指定线程执行,以及如何利用withContext和async/await进行并发操作。此外,还展示了如何取消协程的执行。
826

被折叠的 条评论
为什么被折叠?



