Coroutine翻译为协程,Google翻译为协同程序,一般也称为轻量级线程,但需要注意的是线程是操作系统里的定义概念,而协程是程序语言实现的一套异步处理的方法。
在Kotlin文档中,Coroutine定义为一个可被挂起的计算实例,下面话不多说了,来一起看看详细的介绍吧。
配置
build.gradle中dependencies添加下面2行,注意coroutine目前仍处于experiment阶段,但Kotline官方保证向前兼容。
dependencies{
implementation'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.22.5'
implementation"org.jetbrains.kotlinx:kotlinx-coroutines-android:0.19.3"
}
实例
我们看一个简单Android示例:
activity_coroutine.xml
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".coroutine.CoroutineActivity">
android:id="@+id/tvHello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
CoroutineActivity.kt
classCoroutineActivity:AppCompatActivity(){
overridefunonCreate(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_coroutine)
setup()
}
funsetup(){
launch(UI){//launchcoroutineinUIcontext
for(iin10downTo1){//countdownfrom10to1
tvHello.text="Countdown$i..."//updatetext
delay(1000)//waithalfasecond
}
tvHello.text="Done!"
}
}
}
运行程序tvHello从10倒计时显示到1,最后显示"Done!"
代码分析:
我们重点分析setup()函数
launch(UI){...}-----在UIcontext下启动coroutine
delay(1000)----将当前coroutine挂起1秒
看到这里你可能会疑惑,Android开发中不是禁止在主线程下做延迟或者阻塞操作吗?
我们回顾下Coroutine的定义:一个可被挂起的计算实例。
Coroutine不是线程,所以挂起Coroutine不会影响当前线程的运行。
取消Coroutine运行
我们修改下上面的代码:
classCoroutineActivity:AppCompatActivity(){
lateinitvarjob:Job
overridefunonCreate(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_coroutine)
setup()
}
funsetup(){
job=launch(CommonPool){//launchcoroutineinUIcontext
for(iin10downTo1){//countdownfrom10to1
tvHello.text="Countdown$i..."//updatetext
delay(1000)//waithalfasecond
}
tvHello.text="Done!"
}
}
overridefunonPause(){
super.onPause()
job.cancel()
}
}
重点是launch(UI)返回给一个job实例,通过job.cancel()取消coroutine。
Coroutine和thread关系
我们再分析下
launch(UI)
这行代码是指将coroutine指派在UI线程上运行
当我们运行一段cpu耗时操作时,则需要将coroutine指定在非UI线程上。
我们写成:
launch(){...}
这行代码等价于:
launch(CommonPool){...}
我们分析下CommonPool的实现,发现它会根据当前cpu的核数创建一个线程池提供给Coroutine使用。
privatefuncreatePlainPool():ExecutorService{
valthreadId=AtomicInteger()
returnExecutors.newFixedThreadPool(defaultParallelism()){
Thread(it,"CommonPool-worker-${threadId.incrementAndGet()}").apply{isDaemon=true}
}
}
privatefundefaultParallelism()=(Runtime.getRuntime().availableProcessors()-1).coerceAtLeast(1)
通过上面的分析,我们理解了Coroutine是一个运行在线程上的可被挂起的计算单元实例,对Coroutine的delay,cancel操作不会影响线程的运行,所以使用Coroutine,可以使我们更加方便得处理异步操作,比如网络请求,数据存储等。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值。
网友评论