簡體   English   中英

Kotlin 等待與協程的異步

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM