在 Java 时代,RxJava 是 Android 开发非常非常重要的组成,RxJava可以大大降低了我们切换线程的成本。随着 Android 把 Kotlin 作为了第一开发语言,Kotlin 时代已经到来,然而在Kotlin 时代,已经有对线程更好的代替品 协程 Coroutine
,他比 RxJava 更加优秀,更加方便操控线程。我们要怀着开放的心态迎接 Kotlin + 协程的到来。
最简单的协程示例
引入依赖
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
编写示例代码
fun main() {
GlobalScope.launch {
delay(1000)
print("World!")
}
print("Hello ")
Thread.sleep(2000)
}
输出结果
Hello World!
Android 第一个协程示例
从前面一个例子,有些人可能有些懵了,这个和我们new 一个线程打印有何区别,从接下来的结合Android主线程的例子,我们就可以清楚协程的工作方式。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MainScope().launch {
val startTime = System.currentTimeMillis()
println("tag1:" + Thread.currentThread().name)
val text1 = withContext(Dispatchers.IO) {
println("tag2:" + Thread.currentThread().name)
delay(1000)
"Hello "
}
val text2 = withContext(Dispatchers.IO) {
println("tag3:" + Thread.currentThread().name)
delay(1000)
"World!"
}
println("tag4:" + Thread.currentThread().name)
println(text1 + text2)
println("耗时:" + (System.currentTimeMillis() - startTime))
}
}
}
输出结果:
System.out: tag1:main
System.out: tag2:DefaultDispatcher-worker-2
System.out: tag3:DefaultDispatcher-worker-1
System.out: tag4:main
System.out: Hello World!
System.out: 耗时:2031
上面的例子中,我们模拟了两个耗时操作,必须要在异步线程实现处理,处理完成后需要在主线程输出结果,如果不使用协程,上面的实现将变得更加麻烦。
定义 suspend 挂起方法
我们对上面的示例进行改进,定义
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MainScope().launch {
val startTime = System.currentTimeMillis()
println("tag1:" + Thread.currentThread().name)
val text1 = getHello()
val text2 = getWorld()
println("tag4:" + Thread.currentThread().name)
println(text1 + text2)
println("耗时:" + (System.currentTimeMillis() - startTime))
}
}
private suspend fun getHello(): String {
return withContext(Dispatchers.IO) {
println("tag2:" + Thread.currentThread().name)
delay(1000)
"Hello "
}
}
private suspend fun getWorld(): String {
return withContext(Dispatchers.IO) {
println("tag3:" + Thread.currentThread().name)
delay(1000)
"World!"
}
}
}
输出结果
System.out: tag1:main
System.out: tag2:DefaultDispatcher-worker-2
System.out: tag3:DefaultDispatcher-worker-3
System.out: tag4:main
System.out: Hello World!
System.out: 耗时:2032
使用 async 改进上面例子
使用了 async 关键字意味着,tag2和tag3不是阻塞的,是并行调用的,后面通过 await() 进行结果等待返回,实现原理可以参考 java 线程中的 notify() 和 await() 。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MainScope().launch {
val startTime = System.currentTimeMillis()
println("tag1:" + Thread.currentThread().name)
val text1 = async { getHello() }
val text2 = async { getWorld() }
println("tag4:" + Thread.currentThread().name)
println(text1.await() + text2.await())
println("耗时:" + (System.currentTimeMillis() - startTime))
}
}
private suspend fun getHello(): String {
return withContext(Dispatchers.IO) {
println("tag2:" + Thread.currentThread().name)
delay(1000)
"Hello "
}
}
private suspend fun getWorld(): String {
return withContext(Dispatchers.IO) {
println("tag3:" + Thread.currentThread().name)
delay(1000)
"World!"
}
}
}
输出结果:
System.out: tag1:main
System.out: tag4:main
System.out: tag2:DefaultDispatcher-worker-1
System.out: tag3:DefaultDispatcher-worker-3
System.out: Hello World!
System.out: 耗时:1070
网友评论