扣丁学堂Android开发Kotlin学习教程之协程Coroutine

  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

  <?xmlversion="1.0"encoding="utf-8"?>

  <android.support.constraint.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"

  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">

  <TextView

  android:id="@+id/tvHello"

  android:layout_width="wrap_content"

  android:layout_height="wrap_content"/>

  </android.support.constraint.ConstraintLayout>

  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,可以使我们更加方便得处理异步操作,比如网络请求,数据存储等。

  以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值。

猜你喜欢

转载自blog.csdn.net/codingker/article/details/81082128