等到Kotlin协程在onCreateView()中完成 [英] Wait until Kotlin coroutine finishes in onCreateView()

查看:96
本文介绍了等到Kotlin协程在onCreateView()中完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在onCreateView中有一个初始化块,其中一些变量是从SharedPreferences,数据库或网络(当前是从SharedPreferences)分配的.

I have an initialization block in onCreateView, where some variables are assigned from SharedPreferences, DB or Network (currently from SharedPreferences).

我想用onViewCreated中的这些值更新视图.但是它们会在onCreateView中的协程完成之前以空值更新.如何等待协程在主线程中完成?

I want to update views with these values in onViewCreated. But they update with empty values before a coroutine in onCreateView finishes. How to wait until the coroutine finishes in main thread?

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)

UPDATE (20-05-2019)

当前我不使用onViewCreated.我在onCreateonCreateView中编写代码.在onCreateView中,我以这种方式访问​​视图:view.country.text = "abc",依此类推.

Currently I don't use onViewCreated. I write code in onCreate and onCreateView. In onCreateView I access views this way: view.country.text = "abc" and so on.

推荐答案

在您的情况下,您无需将GlobalScope用作协程上下文(可以,但根据文档建议不推荐使用).您需要一个本地范围:

In your case you don't need to use GlobalScope as a coroutine context (you can but it is not recommended as per docs). You need a local scope:

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

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

另外,您的片段应实现CoroutineScope并在Android中使用Dispatchers.Main来向应用程序的build.gradle添加依赖项:

Also your fragment should implement CoroutineScope and to use Dispatchers.Main in Android add dependency to app's 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)
    }
}

这篇关于等到Kotlin协程在onCreateView()中完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆