Во-первых, я бы изменил вашу функцию loadData на функцию приостановки вместо использования launch
. Лучше иметь возможность определить на сайте вызова, как вы хотите продолжить выполнение. Например, при выполнении теста вы можете назвать свою сопрограмму внутри runBlocking
. Вы также должны правильно реализовать структурированный параллелизм вместо того, чтобы полагаться на 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()
}