Инициализация Kotlin CoroutineScope в зависимости от CoroutineContext с пользовательским геттером - PullRequest
0 голосов
/ 18 января 2019

Google codelab Комната Android с видом - Kotlin имеет следующий фрагмент :

class WordViewModel(application: Application) : AndroidViewModel(application) {

    // ...

    private val coroutineContext: CoroutineContext
       get() = parentJob + Dispatchers.Main

    private val scope = CoroutineScope(coroutineContext)

    // ...

}

И из того, что я понимаю из этого ответа, пользовательский метод получения вычисляется каждый раз, тогда как назначение оценивается только во время конструирования. Таким образом, в действительности, scope будет принимать значение, которое не изменится позже, так что для чего нужен пользовательский метод получения для coroutineContext?

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Определение coroutineContext как вычисляемого свойства (или пользовательского метода получения) имеет больше смысла, когда вы определяете CoroutineScope в компоненте с жизненным циклом (то есть Android Activity). Пример в Javadoc не требует пояснений:

class MyActivity : AppCompatActivity(), CoroutineScope {
    lateinit var job: Job
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        job = Job()
    }

    override fun onDestroy() {
        super.onDestroy()
        job.cancel() // Cancel job on activity destroy. After destroy all children jobs will be cancelled automatically
    }
}

В этом случае вы создаете Job в методе жизненного цикла, поэтому вам нужно, чтобы вычисленное свойство возвращало coroutineContext с экземпляром Job, созданным в onCreate.

0 голосов
/ 18 января 2019

Я думаю, что в этом примере мы можем избавиться от

private val coroutineContext: CoroutineContext
   get() = parentJob + Dispatchers.Main

и просто напишите

private val scope = CoroutineScope(parentJob + Dispatchers.Main)

Таким образом, код результата будет выглядеть так:

class WordViewModel(application: Application) : AndroidViewModel(application) {
    private var parentJob = Job()
    private val scope = CoroutineScope(parentJob + Dispatchers.Main)
    // ...
}

Полагаю, в данном случае писать геттер - дело стиля. Ничего не изменится, если мы удалим его.

...