我有一个协程程序,我想在启动页面时启动Android启动程序.我想等数据出来后再开始下一项活动.做这件事最好的方法是什么?目前我们的Android正在使用实验性的协程0.26.0……现在还不能改变这一点.

更新:我们现在使用的是最新的协同程序,不再是实验性的

onResume() {
    loadData()
}

fun loadData() = GlobalScope.launch {
    val job = GlobalScope.async {
        startLibraryCall()
    }
    // TODO await on success
    job.await()
    startActivity(startnewIntent)
}

fun startLibraryCall() {
    val thirdPartyLib() = ThirdPartyLibrary()
    thirdPartyLib.setOnDataListener() { 
        ///psuedocode for success/ fail listeners
        onSuccess -> ///TODO return data
        onFail -> /// TODO return other data
    }
}

推荐答案

第一点是,我会将loadData函数更改为挂起函数,而不是使用launch.最好 Select 在调用点定义您希望如何继续执行.例如,在实现测试时,您可能希望在runBlocking中调用协程.您还应该正确实现structured concurrency,而不是依赖GlobalScope.

On the other side of the problem I would implement an extension function on the ThirdPartyLibrary that turns its async calls into a suspending function. This way you will ensure that the calling coroutine actually waits for the Library call to have some value in it.

由于我们将loadData设为挂起函数,现在可以确保它只在ThirdPartyLibrary调用结束时启动新活动.

import kotlinx.coroutines.*
import kotlin.coroutines.*

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

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

    override fun onDestroy() {
        super.onDestroy()
        masterJob.cancel()
    }

    override fun onResume() {
        this.launch {
            val data = ThirdPartyLibrary().suspendLoadData()
            // TODO: act on data!
            startActivity(startNewIntent)
        }
    }
}

suspend fun ThirdPartyLibrary.suspendLoadData(): Data = suspendCoroutine { cont ->
    setOnDataListener(
            onSuccess = { cont.resume(it) },
            onFail = { cont.resumeWithException(it) }
    )
    startLoadingData()
}

Kotlin相关问答推荐

只能在元素区域中点击的Jetpack Compose列

带有Spring Boot和Kotline的可嵌入实体

访问者闭包中的Kotlin序列yield 率

Kotlin 说不需要强制转换,但删除后会出现新警告

Kotlin 中的 maxOf() 和 max() 方法有什么区别?

如何在 Spring Boot 3 中为内部类提供运行时提示

Kotlin 可空泛型

Kotlin 函数有 2 个参数用于对 Map 或 List 进行排序

如何创建扩展函数isNullOrEmpty?

Kotlin 使用委托进行隐式覆盖

T except one class

未为任务启用 Gradle 构建缓存

将 jetpack compose 添加到现有元素

如何在 android jetpack compose 中相互重叠列表项?

使用 Paging 3 时保存并保留 LazyColumn 滚动位置

Kotlin not nullable值可以为null吗?

Kotlin:如何修改成对的值?

在Kotlin中使用@Service时引发异常

Kotlin Android:属性委托必须有一个 'getValue(DashViewModel, KProperty*>)' 方法

Android:Exoplayer - ExtractorMediaSource 已弃用