我有一个协程,我想在启动页面期间在 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
。最好能够选择在调用站点定义您希望如何继续执行。例如,在实现测试时,您可能想在runBlocking
。您还应该实施结构化并发 https://medium.com/@elizarov/structured-concurrency-722d765aa952正确地而不是依赖GlobalScope
.
在问题的另一方面,我将在ThirdPartyLibrary
将其异步调用转变为挂起函数。这样,您将确保调用协程实际上等待库调用具有某些值。
自从我们做了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()
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)