协程上下文自定义获取器

时间:2018-11-06 21:17:03

标签: android kotlin kotlinx.coroutines

我正在研究1.0.0发行后与Android相关的kotlin协程。

我发现了无数示例,这些示例包括创建范围内的ViewModel(从arch组件),创建父作业并在onCleared中将其清除,或范围内的Activity在onCreate中进行作业并在onDestroy中进行清除(与onResumeonPause相同)。在某些示例中,我遇到了以下代码结构(摘自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
  }
}

1 个答案:

答案 0 :(得分:3)

我认为,当您像在更新中一样延迟提供1st, 2nd, 3rd, 4th, 5th and 18th时,可能会遇到线程安全问题,因为该代码是从启动协程的任何线程中评估的。 另一方面,最初的示例确保Job是从Main线程设置的,并且要在典型的android活动中启动其他线程之前进行。

您可以通过在范围的开头创建整个inner list来实现与初始示例相似的功能。这也消除了为每个启动的协程计算最终上下文的需要。例如:

big

或者,如果您不喜欢它扔

out = [['ACAD9', 'ENSG00000177646', 'chr1', 'ENSEMBL', 'exon', '13403', '13655', '"ACAD9";']]