我正在研究1.0.0发布后与Android相关的kotlin协程.
我发现了无数示例,这些示例包括创建父级作业,在onCleared或范围内的Activity中创建作用域viewmodel(由arch组件),在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 }}
解决方法:
我认为,像在更新中那样延迟地提供Job时,可能会遇到线程安全问题,因为该代码是从启动协程的任何线程中评估的.
另一方面,最初的示例确保Job是从Main线程设置的,并且确保它可以在典型的androID活动中启动其他线程之前发生.
您可以通过在范围的开头创建整个CoroutineContext来实现与初始示例类似的 *** 作.这也消除了为每个启动的协程计算最终上下文的需要.例如:
class lifecycleCrScope : Coroutinescope, lifecycleObserver { private var _ctx: CoroutineContext? = null overrIDe val coroutineContext: CoroutineContext get() = _ctx!! // throws when not within scope private fun startScope() { _ctx = dispatchers.Main + Job() } private fun endScope() { _ctx!![Job]!!.cancel() // throws only when misused, e.g. no startScope() _ctx = null } @OnlifecycleEvent(ON_RESUME) // <-. fun resume() { // | Beware: startScope() // | symmetric but no scope } // | during onCreate, // | onStart, onStop, ... @OnlifecycleEvent(ON_PAUSE) // <-. fun pause() { endScope() }}
或者,如果您不喜欢扔
class lifecycleCrScope : Coroutinescope, lifecycleObserver { // initially cancelled. Jobs started outsIDe scope will not execute silently private var _ctx: CoroutineContext = dispatchers.Main + Job().apply { cancel() } .. private fun endScope() { _ctx[Job]!!.cancel() // should never throw } ..
总结 以上是内存溢出为你收集整理的协程上下文自定义获取器全部内容,希望文章能够帮你解决协程上下文自定义获取器所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)