Доступ к пользовательскому элементу контекста сопрограммы внутри задания сопрограммы - PullRequest
0 голосов
/ 26 сентября 2019

Когда пользователь вводит EditText, я запускаю сопрограмму для поиска данных из бэкэнда.Я также хочу отменить любой существующий поиск Job s.Насколько я понимаю, если я помещу объект контекста в launch(), я смогу получить к нему доступ позже, но кажется, что job[JobType] всегда возвращает null для меня.

Я что-то здесь неправильно понимаю?Есть ли лучший способ добиться этого?

class MyViewModel : ViewModel() {

    private val jobs = CopyOnWriteArrayList<Job>()

    sealed class JobType() : AbstractCoroutineContextElement(JobType) {
        companion object Key : CoroutineContext.Key<JobType>

        object SearchJob : JobType()
        object OtherJob : JobType()
    }

    fun search(query: String) = viewModelScope.launch(JobType.SearchJob) {
         //coroutineContext[JobType] gives JobType.SearchJob
         //but following doesn't work because job[JobType] is always null

         jobs.filter { it[JobType] == JobType.SearchJob }
                            .forEach { if (it != this) it.cancel() }
        //search online
    }.also {
        track(it)
    }

    private fun track(job: Job) {
        jobs.add(job)
        job.invokeOnCompletion {
            jobs.remove(job)
        }
    }
}

1 Ответ

0 голосов
/ 26 сентября 2019

Если вы только звоните search в основном потоке.

class MyViewModel : ViewModel() {

    private var searchJob: Job? = null

    fun search(query: String): Job {
        searchJob?.cancel()
        searchJob = viewModelScope.launch {
            //search online
        }
        return searchJob
    }
}
...