问题描述
我有一个协程,我想在启动页面期间在android启动时启动.我想等待数据返回,然后再开始下一个活动.做这个的最好方式是什么?目前,我们的android系统正在使用实验性协程0.26.0 ...目前尚无法更改.
I have a coroutine I'd like to fire up at android startup during the splash page. I'd like to wait for the data to come back before I start the next activity. What is the best way to do this? Currently our android is using experimental coroutines 0.26.0...can't change this just yet.
更新:我们现在正在使用最新的协程,而不再是实验性的
UPDATED: We are now using the latest coroutines and no longer experimental
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
中调用协程.您还应该正确实现结构并发,而不要依赖GlobalScope
.
The first point is that I would change your loadData function into a suspending function instead of using launch
. It's better to have the option to define at call site how you want to proceed with the execution. For example when implementing a test you may want to call your coroutine inside a runBlocking
. You should also implement structured concurrency properly instead of relying on GlobalScope
.
在问题的另一方面,我将在ThirdPartyLibrary
上实现扩展功能,将其异步调用转换为挂起函数.这样,您可以确保调用协程实际上等待Library调用具有一定的价值.
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
调用完成时才开始新的活动.
Since we made loadData
a suspending function we can now ensure that it will only start the new activity when the ThirdPartyLibrary
call finishes.
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()
}
这篇关于在协程中的侦听器中等待数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!