LiveData 更改时不会触发观察者 - Kotlin
Observers not being triggered whe LiveData changes - Kotlin
我知道这个问题已经被问过几次了,但我这里有一个有趣的情况,我想不通。
我有一个带有“TASKS”的 database
,除了 writing/updating 方法之外,我调用了两次 get 方法:一次用于获取最后创建的任务,另一次用于 select ID
的特定任务
@Query("SELECT * FROM tasks_history_table ORDER BY taskId DESC LIMIT 1")
suspend fun getCurrentTask(): Task2?
@Query("SELECT * from tasks_history_table WHERE taskId = :key ")
suspend fun get(key: Long): Task2?
然后在 viewModel
中,我每次调用这些方法之一时都会启动一个 coroutine
。
这是最后创建的任务:
private fun initializeCurrentTask(){
viewModelScope.launch {
_currentTask.value = getCurrentTaskFromDatabase()!!
}
}
suspend fun getCurrentTaskFromDatabase(): Task2? {
var currentTask = database.getCurrentTask()
return currentTask
}
而这个是针对特定任务的
fun initializeSelectedTask(){
viewModelScope.launch {
_currentTask.value = getSelectedTaskFromDatabase(selectedTaskId.value!!)!!
}
}
suspend fun getSelectedTaskFromDatabase(taskId: Long): Task2? {
var currentTask = database.get(selectedTaskId.value!!)!!
return currentTask
}
所以除了传递的参数 Id 不同外,它们几乎相同。
然后,我将该数据发送到 Fragment
以更新 UI,通过 LiveData
private val _currentTask = MutableLiveData<Task2>()
val currentTask : LiveData<Task2>
get() = _currentTask
这里是 observer
:
timerViewModel.currentTask.observe(viewLifecycleOwner) {
updateUIText()
updateCountdownUI()
updateAnimation()
}
每次我调用函数来获取 las 保存的任务时,都会调用 observers
并且一切正常。但是每当我调用该函数以通过 Id 获取特定任务时,都不会调用 observers
。
我已经设置了 Logs
,我得出的结论是 LiveData
正在更新,但 observer
没有被触发。
这是存储库,以防有人查看。谢谢!!
https://github.com/arieldipietro/PomodoroTechnique
在 FragmentTimer
和 FragmentHistory
中,您创建了 viewModel
个实例,使用它们各自的 fragments
作为所有者,这使得它们观察 liveData
这是仅由它们的实例触发。因此,现在当您从 FragmentHistory
触发任务时,它不会在 FragmentTimer
.
中被观察到
您需要使用 SharedViewModel
在片段之间传递数据,您必须使用 activity
作为其所有者创建 TimerViewModel
的对象,然后您将能够从 FragmentTimer
。在 ViewModelProvider
的构造函数中将 requireActivity()
作为所有者传递。
timerViewModel = ViewModelProvider(requireActivity(), viewModelFactory)[TimerViewModel::class.java]
您可以在 codelab tutorial 中阅读更多相关信息。
我知道这个问题已经被问过几次了,但我这里有一个有趣的情况,我想不通。
我有一个带有“TASKS”的 database
,除了 writing/updating 方法之外,我调用了两次 get 方法:一次用于获取最后创建的任务,另一次用于 select ID
@Query("SELECT * FROM tasks_history_table ORDER BY taskId DESC LIMIT 1")
suspend fun getCurrentTask(): Task2?
@Query("SELECT * from tasks_history_table WHERE taskId = :key ")
suspend fun get(key: Long): Task2?
然后在 viewModel
中,我每次调用这些方法之一时都会启动一个 coroutine
。
这是最后创建的任务:
private fun initializeCurrentTask(){
viewModelScope.launch {
_currentTask.value = getCurrentTaskFromDatabase()!!
}
}
suspend fun getCurrentTaskFromDatabase(): Task2? {
var currentTask = database.getCurrentTask()
return currentTask
}
而这个是针对特定任务的
fun initializeSelectedTask(){
viewModelScope.launch {
_currentTask.value = getSelectedTaskFromDatabase(selectedTaskId.value!!)!!
}
}
suspend fun getSelectedTaskFromDatabase(taskId: Long): Task2? {
var currentTask = database.get(selectedTaskId.value!!)!!
return currentTask
}
所以除了传递的参数 Id 不同外,它们几乎相同。
然后,我将该数据发送到 Fragment
以更新 UI,通过 LiveData
private val _currentTask = MutableLiveData<Task2>()
val currentTask : LiveData<Task2>
get() = _currentTask
这里是 observer
:
timerViewModel.currentTask.observe(viewLifecycleOwner) {
updateUIText()
updateCountdownUI()
updateAnimation()
}
每次我调用函数来获取 las 保存的任务时,都会调用 observers
并且一切正常。但是每当我调用该函数以通过 Id 获取特定任务时,都不会调用 observers
。
我已经设置了 Logs
,我得出的结论是 LiveData
正在更新,但 observer
没有被触发。
这是存储库,以防有人查看。谢谢!! https://github.com/arieldipietro/PomodoroTechnique
在 FragmentTimer
和 FragmentHistory
中,您创建了 viewModel
个实例,使用它们各自的 fragments
作为所有者,这使得它们观察 liveData
这是仅由它们的实例触发。因此,现在当您从 FragmentHistory
触发任务时,它不会在 FragmentTimer
.
您需要使用 SharedViewModel
在片段之间传递数据,您必须使用 activity
作为其所有者创建 TimerViewModel
的对象,然后您将能够从 FragmentTimer
。在 ViewModelProvider
的构造函数中将 requireActivity()
作为所有者传递。
timerViewModel = ViewModelProvider(requireActivity(), viewModelFactory)[TimerViewModel::class.java]
您可以在 codelab tutorial 中阅读更多相关信息。