服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Kotlin学习教程之协程Coroutine

Kotlin学习教程之协程Coroutine

2022-02-22 15:20wenson123 Android

这篇文章主要给大家介绍了关于Kotlin学习教程之协程Coroutine的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

定义

Coroutine翻译为协程,Google翻译为协同程序,一般也称为轻量级线程,但需要注意的是线程是操作系统里的定义概念,而协程是程序语言实现的一套异步处理的方法。

在Kotlin文档中,Coroutine定义为一个可被挂起的计算实例,下面话不多说了,来一起看看详细的介绍吧。

配置

build.gradle中dependencies 添加下面2行,注意coroutine目前仍处于experiment阶段,但Kotline官方保证向前兼容。

?
1
2
3
4
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns: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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CoroutineActivity : AppCompatActivity() {
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_coroutine)
  setup()
 }
 
 fun setup() {
  launch(UI) { // launch coroutine in UI context
   for (i in 10 downTo 1) { // countdown from 10 to 1
    tvHello.text = "Countdown $i ..." // update text
    delay(1000) // wait half a second
   }
   tvHello.text = "Done!"
  }
 }
}

运行程序 tvHello从10倒计时显示到1,最后显示"Done!"

代码分析:

我们重点分析setup()函数

  • launch(UI) {...} -----在UIcontext下启动coroutine
  • delay(1000) ----将当前coroutine挂起1秒

看到这里你可能会疑惑,Android开发中不是禁止在主线程下做延迟或者阻塞操作吗?

我们回顾下Coroutine的定义:一个可被挂起的计算实例。

Coroutine不是线程,所以挂起Coroutine不会影响当前线程的运行。

取消Coroutine运行

我们修改下上面的代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class CoroutineActivity : AppCompatActivity() {
 lateinit var job:Job
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_coroutine)
  setup()
 }
 
 fun setup() {
  job = launch(CommonPool) { // launch coroutine in UI context
   for (i in 10 downTo 1) { // countdown from 10 to 1
    tvHello.text = "Countdown $i ..." // update text
    delay(1000) // wait half a second
   }
   tvHello.text = "Done!"
  }
 }
 
 override fun onPause() {
  super.onPause()
  job.cancel()
 }
}

重点是 launch(UI)返回给一个job实例,通过job.cancel()取消coroutine。

Coroutine和thread关系

我们再分析下

?
1
launch(UI)

这行代码是指将coroutine指派在UI线程上运行

当我们运行一段cpu耗时操作时,则需要将coroutine指定在非UI线程上。

我们写成:

?
1
launch(){...}

这行代码等价于:

?
1
launch(CommonPool){...}

我们分析下CommonPool的实现,发现它会根据当前cpu的核数创建一个线程池提供给Coroutine使用。

?
1
2
3
4
5
6
7
8
private fun createPlainPool(): ExecutorService {
 val threadId = AtomicInteger()
 return Executors.newFixedThreadPool(defaultParallelism()) {
  Thread(it, "CommonPool-worker-${threadId.incrementAndGet()}").apply { isDaemon = true }
 }
}
 
private fun defaultParallelism() = (Runtime.getRuntime().availableProcessors() - 1).coerceAtLeast(1)

总结:

通过上面的分析,我们理解了Coroutine是一个运行在线程上的可被挂起的计算单元实例,对Coroutine的delay,cancel操作不会影响线程的运行,线程的状态变化对我们是透明的,我们不需要关心。

所以使用Coroutine,可以使我们更加方便得处理异步操作,比如网络请求,数据存储等。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

原文链接:https://www.jianshu.com/p/0ee48f71edbe

延伸 · 阅读

精彩推荐