Подождите, пока сопрограмма Kotlin не завершится в onCreateView () - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть блок инициализации в onCreateView, где некоторые переменные назначаются из SharedPreferences, DB или Network (в настоящее время из SharedPreferences).

Я хочу обновить представления с этими значениями в onViewCreated.Но они обновляются с пустыми значениями до завершения сопрограммы в onCreateView.Как дождаться окончания сопрограммы в главном потоке?

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    ...
    GlobalScope.launch(Dispatchers.Main) {
        val job = GlobalScope.launch(Dispatchers.IO) {
            val task = async(Dispatchers.IO) {
                settingsInteractor.getStationSearchCountry().let {
                    countryName = it.name
                }
                settingsInteractor.getStationSearchRegion().let {
                    regionName = it.name
                }
            }
            task.await()
        }
        job.join()
    }
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    country.updateCaption(countryName)
    region.updateCaption(regionName)
}

ОБНОВЛЕНИЕ (20-05-2019)

В настоящее время я не использую onViewCreated.Я пишу код в onCreate и onCreateViewonCreateView я получаю доступ к представлениям следующим образом: view.country.text = "abc" и т. Д.

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

В вашем случае вам не нужно использовать GlobalScope в качестве сопрограммного контекста (вы можете, но это не рекомендуется согласно документам).Вам нужна локальная область действия:

private var job: Job = Job()
override val coroutineContext: CoroutineContext
    get() = Dispatchers.Main + job

@Override
public void onDestroy() {
    super.onDestroy();
    job.cancel()
}

Также ваш фрагмент должен реализовывать CoroutineScope, а для использования Dispatchers.Main в Android добавить зависимость к build.gradle приложения:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1'

Кодждать окончания сопрограммы:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    launch {
        val operation = async(Dispatchers.IO) {
            settingsInteractor.getStationSearchCountry().let {
                countryName = it.name
            }
            settingsInteractor.getStationSearchRegion().let {
                regionName = it.name
            }
        }
        operation.await() // wait for result of I/O operation without blocking the main thread

        // update views
        country.updateCaption(countryName)
        region.updateCaption(regionName)
    }
}
0 голосов
/ 07 декабря 2018

Один из способов сделать это - запустить запуск в главном потоке

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

GlobalScope.launch(Dispatchers.IO) {
     settingsInteractor.getStationSearchCountry().let {
         countryName = it.name
     }
     settingsInteractor.getStationSearchRegion().let {
         regionName = it.name
     }

     launch(Dispatchers.Main) {
         country.updateCaption(countryName)
         region.updateCaption(regionName)
     }
   }
}
...