fun launchWhenStarted(block: suspend CoroutineScope.() -> Unit): Job = launch {
lifecycle.whenStarted(block)
}
// 当 activity 处于resume的时候执行 协程体
fun launchWhenResumed(block: suspend CoroutineScope.() -> Unit): Job = launch {
lifecycle.whenResumed(block)
}
}
由于上面启动协程的方法绑定了activity
生命周期,所以在activity
destroy
的时候,也实现了自动cancel掉协程
所以我们 CoroutineActivity
Demo的代码可以写的更加简单,如下:
class CoroutineActivity : AppCompatActivity() {
private lateinit var testApi: TestApi
…
fun requestData1() {
lifecycleScope.launchWhenResumed {
try {
val lastedNews = testApi.getLatestNews2()
tv_text.text = lastedNews.stories!![0].title
} catch(e: Exception) {
tv_text.text = “error”
}
}
}
}
同时Google也对LiveData提供了对协程的支持,不过需要添加lifecycle-livedata-ktx
依赖
// 现在还是alpha
版,等正式版发布以后,请替换成正式版
implementation “androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-alpha05”
lifecycle-livedata-ktx
依赖添加了liveData
顶级函数,返回CoroutineLiveData
源码如下:
…
internal const val DEFAULT_TIMEOUT = 5000L
…
fun liveData(
context: CoroutineContext = EmptyCoroutineContext,
timeoutInMs: Long = DEFAULT_TIMEOUT,
@BuilderInference block: suspend LiveDataScope.() -> Unit
): LiveData = CoroutineLiveData(context, timeoutInMs, block)
CoroutineLiveData
是在什么时候启动协程并执行协程体的呢???
internal class CoroutineLiveData(
context: CoroutineContext = EmptyCoroutineContext,
timeoutInMs: Long = DEFAULT_TIMEOUT,
block: Block
) : MediatorLiveData() {
private var blockRunner: BlockRunner?
private var emittedSource: EmittedSource? = null
init {
val scope = CoroutineScope(Dispatchers.Main.immediate + context + supervisorJob)
blockRunner = BlockRunner(
liveData = this,
block = block,
timeoutInMs = timeoutInMs,
scope = scope
) {
blockRunner = null
}
}
…
// observer(观察者)个数有0到1时执行
// 即第一次调用observe或observeForever时执行
override fun onActive() {
super.onActive()
// 启动协程并执行协程体
blockRunner?.maybeRun()
}
// observer(观察者)个数有1到0时执行
// 即调用removeObserver时触发检查并执行回调
override fun onInactive() {
super.onInactive()
// 取消协程
blockRunner?.cancel()
}
}
可见CoroutineLiveData
是在onActive()
启动协程,在onInactive()
取消协程
所以使用LiveData
对协程的支持, 那么CoroutineActivity
Demo的代码写法如下
class CoroutineActivity : AppCompatActivity() {
private lateinit var testApi: TestApi
…
fun requestData1() {
liveData {
try {
val lastedNews = testApi.getLatestNews2()
emit(lastedNews.stories!![0].title!!)
} catch(e: Exception) {
emit(“error”)
}
}.observe(this, Observer {
tv_text.text = it
})
}
}
上面我们讲了协程在android里最常用的用法,下面将介绍协程的一些基本知识
协程上下文用CoroutineContext
表示,kotlin
中 比较常用的Job
、协程调度器(CoroutineDispatcher)
、协程拦截器(ContinuationInterceptor)
等都是CoroutineContext
的子类,即它们都是协程上下文
先看一下CoroutineContext
比较重要的plus
方法,它是一个用operator
修复的重载(+)
号的操作符方法
@SinceKotlin(“1.3”)
public interface CoroutineContext {
/**