我正在建立一个“会话”系统,用户可以在其中启动,完成和查看其会话。
用户浏览第一个片段以创建他的会话,然后进入“会话中”片段。
如果他在完成会话之前返回主菜单,我希望他直接进入“会话中”而不经历“新会话”片段。
所有会话数据都存储在本地数据库中,我使用Kotlin协程从数据库中获取数据(请参见下面的代码示例)
这是我第一次使用协程,我承认它有点模糊 对我来说,所有帮助都是欢迎的
问题是,当用户按下按钮进行导航时,协程完成之后,以查看是否存在当前会话,从而验证空对象或当前会话的上一个会话,因此导航到“新会话”片段
我需要的是一种等待协程完成然后 处理按钮点击
这里编写的所有代码都包含在viewModel内部。
这就是我设置作业/范围的方式
private var viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
这就是我启动协程的方式:
private fun initializeLastSession() {
uiScope.launch {
lastSession.value = getLastSessionFromDatabase()
}
}
private suspend fun getLastSessionFromDatabase(): Session? {
return withContext(Dispatchers.IO) {
var session = database.getLastSession()
session
}
}
验证是在此函数内部进行的
fun isSessionActive(): Boolean {
//Simplified
if (lastSession.value = null) {
return false
} else if (...) {
return true
} else {
return false
}
当用户按下导航按钮时,将从片段itlsef的 if 语句中调用最后一个函数“ isSessionActive”。
如果为true,则导航至“ InSession”,否则导航至“ newSession”
我已经看到了等待协程完成的多种方式,但没有一种与我启动协程的方式相匹配,甚至更少的解决方案对我有用。
答案 0 :(得分:0)
您能否允许我举一个与您的代码无关的简单示例?但与问题密切相关:
uiScope.launch{
withContext(Dispatchers.IO){
val dataFromDatabase = getSomeDataFromDatabase()
if (dataFromDatabase.notEmpty()){ //or something
withContext(Dispatchers.Main){
//send data to fragment here :)
}
}
}
}
编辑:
由于您说自己在ViewModel
中,因此不需要返回任何值,因此需要观察更改后的值:
//on top of your ViewModel class:
val yourVariableName: MutableLiveData<Boolean> = MutableLiveData()
//than in your method:
uiScope.launch{
withContext(Dispatchers.IO){
val dataFromDatabase = getSomeDataFromDatabase()
if (dataFromDatabase.notEmpty()){ //or something
withContext(Dispatchers.Main){
if (lastSession.value = null) {
yourVariableName.value = false
} else if (...) {
yourVariableName.value = true
} else {
yourVariableName.value = false
}
}
}
}
}
并且比您的片段中的
//after you have successfully instantiated the `ViewModel`:
mViewModel.yourVariableName.observe(this , Observer{ valueYouAreObserving->
// and here you have the value true ore false
Log.d("Tag", $valueYouAreObserving)
})