第一点是,我会将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()
}