设置超时
这个相当于系统封装了自动取消功能,对应函数withTimeout
lifecycleScope.launch {
try {
withTimeout(1000) {
val text = getText()
tvTest.text = text
}
} catch (e:Exception){
e.printStackTrace()
}
}
带返回值的Job
与launch类似的还有一个async方法,它会返回一个Deferred对象,属于Job的扩展类,Deferred可以获取返回的结果,具体使用如下
lifecycleScope.launch {
val one= async {
delay(1000)
return@async 1
}
val two= async {
delay(2000)
return@async 2
}
Log.i(“scope test”,(one.await()+two.await()).toString())
}
自定义CoroutineScope
先看CoroutineScope源码
public interface CoroutineScope {
public val coroutineContext: CoroutineContext
}
CoroutineScope中主要包含一个coroutineContext对象,我们要自定义只需实现coroutineContext的get方法
class TestScope() : CoroutineScope {
override val coroutineContext: CoroutineContext
get() = TODO(“Not yet implemented”)
}
要创建coroutineContext,得要先知道CoroutineContext是什么,我们再看CoroutineContext源码
/**
-
Persistent context for the coroutine. It is an indexed set of [Element] instances.
-
An indexed set is a mix between a set and a map.
-
Every element in this set has a unique [Key].
*/
public interface CoroutineContext {
public operator fun get(key: Key): E?
public fun fold(initial: R, operation: (R, Element) -> R): R
public operator fun plus(context: CoroutineContext): CoroutineContext =
…
public fun minusKey(key: Key<*>): CoroutineContext
public interface Key
public interface Element : CoroutineContext {
…
}
}
通过注释说明,我们知道它本质就是一个包含Element的集合,只是不像set和map集合一样,它自己实现了获取(get),折叠(fold,添加和替换的组合),相减(minusKey,移除),对象组合(plus,如val coroutineContext=coroutineContext1+coroutineContext2)
它的主要内容是Element,而Element的实现有
-
Job 任务
-
ContinuationInterceptor 拦截器
-
AbstractCoroutineContextElement
-
CoroutineExceptionHandler
-
ThreadContextElement
-
DownstreamExceptionElement
-
…
可以看到很多地方都有实现Element,它主要目的是限制范围以及异常的处理。这里我们先了解两个重要的Element,一个是Job,一个是CoroutineDispat