[英]Kotlin wait for async with coroutine
我想在 phoneViewModel 和 ScanViewModel 實例化時打開一個新活動。 它們通過調用異步函數 InitialRead() 來實例化。 我正在記錄每一步,atm 它們被記錄為 done3 => done2 => done1
我想按以下順序排列它們:done1 => done2 => done3
我有以下代碼:
class MainBusinessActivity : AppCompatActivity() {
private lateinit var scanViewModel: ScanViewModel
private lateinit var phoneViewModel: PhoneViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main_business)
}
private fun startEntitySetListActivity() = GlobalScope.async {
val sapServiceManager = (application as SAPWizardApplication).sapServiceManager
sapServiceManager?.openODataStore {
phoneViewModel = ViewModelProvider(this@MainBusinessActivity).get(PhoneViewModel::class.java).also {it.initialRead{Log.e("done", "done1")}}
scanViewModel = ViewModelProvider(this@MainBusinessActivity).get(ScanViewModel::class.java).also {it.initialRead{Log.e("done", "done2")}}
}
}
override fun onResume() {
super.onResume()
//startEntitySetListActivity()
runBlocking {
startEntitySetListActivity().await()
val intent = Intent(this@MainBusinessActivity, HomeActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
Log.e("done", "done3")
startActivity(intent)
}
}
}
我究竟做錯了什么? 有人可以更正我的代碼嗎?
切勿在 Android 應用中使用runBlocking
。 runBlocking
完全違背了使用協程的目的,並可能導致 ANR。 您也可能永遠不應該使用GlobalScope
,這會導致 UI 泄漏。 您可能需要它來執行某種長時間運行的任務,這些任務對放入服務沒有意義但不依賴於任何 UI 組件,但我想不出任何例子
您也不應該在后台實例化您的 ViewModel。 這應該在onCreate()
。
將該函數設為掛起函數,可以在后台同時分解兩個任務,然后返回。
先從你的協同程序lifecycleScope
。
假設sapServiceManager?.openODataStore
是一個需要回調的異步任務,您需要將它包裝在suspendCoroutine
。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main_business)
phoneViewModel = ViewModelProvider(this@MainBusinessActivity).get(PhoneViewModel::class.java)
scanViewModel = ViewModelProvider(this@MainBusinessActivity).get(ScanViewModel::class.java)
}
private suspend fun startEntitySetListActivity() = coroutineScope {
val sapServiceManager = (application as SAPWizardApplication).sapServiceManager
sapServiceManager ?: return
suspendCoroutine<Unit> { continuation ->
sapServiceManager.openODataStore { continuation.resume(Unit) }
}
listOf(
launch {
phoneViewModel.initialRead{Log.e("done", "done1")}
},
launch {
scanViewModel.initialRead{Log.e("done", "done2")}
}
).joinAll()
}
override fun onResume() {
super.onResume()
lifecycleScope.launch {
startEntitySetListActivity()
val intent = Intent(this@MainBusinessActivity, HomeActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
Log.e("done", "done3")
startActivity(intent)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.