我正在研究1.0.0发行后与Android相关的kotlin协程。
我发现了无数示例,这些示例包括创建范围内的ViewModel(从arch组件),创建父作业并在onCleared
中将其清除,或范围内的Activity在onCreate
中进行作业并在onDestroy
中进行清除(与onResume
和onPause
相同)。在某些示例中,我遇到了以下代码结构(摘自official docs):
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
当我们从该范围启动新的协程时,是否一直在调用此自定义getter?不好吗也许最好保留单个作用域值,而不是每次都创建一个新的作用域值?
[更新]
如果我们摆脱lateinit
工作并匆忙创建它,那么我接受该解决方案,但是如果我想做这样的事情该怎么办(我应该怎么做?该解决方案看起来正确还是不正确?) :
class LifecycleCrScope: CoroutineScope, LifecycleObserver {
private var _job: Job? = null
override val coroutineContext: CoroutineContext
get() = job() + Dispatchers.Main
fun job() : Job {
return _job ?: createJob().also { _job = it }
}
fun createJob(): Job = Job() // or another implementation
@OnLifecycleEvent(ON_PAUSE)
fun pause() {
_job?.cancel()
_job = null
}
}
答案 0 :(得分:3)
我认为,当您像在更新中一样延迟提供1st, 2nd, 3rd, 4th, 5th and 18th
时,可能会遇到线程安全问题,因为该代码是从启动协程的任何线程中评估的。
另一方面,最初的示例确保Job是从Main线程设置的,并且要在典型的android活动中启动其他线程之前进行。
您可以通过在范围的开头创建整个inner list
来实现与初始示例相似的功能。这也消除了为每个启动的协程计算最终上下文的需要。例如:
big
或者,如果您不喜欢它扔
out = [['ACAD9', 'ENSG00000177646', 'chr1', 'ENSEMBL', 'exon', '13403', '13655', '"ACAD9";']]