观察者没有被触发在更改时-Kotlin

发布于 2025-01-25 11:32:11 字数 2007 浏览 3 评论 0原文

我知道这个问题已经被问到了几次,但是我在这里有一个有趣的情况,我不知道。

我有一个带有“任务”的数据库,除了写作/更新方法之外,我将“ Get Method”命名为两次:一个用于获取最后一个创建的任务,另一个是通过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以通过livedata更新UI,

private val _currentTask = MutableLiveData<Task2>()
    val currentTask : LiveData<Task2>
        get() = _currentTask

这是observer

timerViewModel.currentTask.observe(viewLifecycleOwner) {
            updateUIText()
            updateCountdownUI()
            updateAnimation()
        }

我每次调用该函数获取LAS保存的任务,调用观察者,一切正常。但是,每当我调用该函数以通过ID获得特定任务时,观察者都不会调用。

我已经设置了logs,并且得出的结论是,livedata正在更新,但是observer未触发。

这是回购,以防有人可以看一下。谢谢!! https://github.com/arieldipiepietro/pomodorotechnique

I know this question has been asked a couple of times, but I have a funny situation here that I can't figure out.

I have a database with "TASKS" and, apart from the writing/updating methods, I'm calling the get method twice: one for getting the last created task, and another to select an specific task by 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?

Then in the viewModel I'm launching a coroutine for each time I call one of these methods.

This one for the last created Task:

private fun initializeCurrentTask(){
    viewModelScope.launch {
        _currentTask.value = getCurrentTaskFromDatabase()!!
    }
}
suspend fun getCurrentTaskFromDatabase(): Task2? {
    var currentTask = database.getCurrentTask()
    return currentTask
    }

And this one for the specific task

fun initializeSelectedTask(){
        viewModelScope.launch {
            _currentTask.value = getSelectedTaskFromDatabase(selectedTaskId.value!!)!!
        }
    }
    suspend fun getSelectedTaskFromDatabase(taskId: Long): Task2? {
        var currentTask = database.get(selectedTaskId.value!!)!!
        return currentTask
    }

So they are both pretty much the same, except for the parameter Id passed.

Then, I'm sending that data to the Fragment to update the UI, via LiveData

private val _currentTask = MutableLiveData<Task2>()
    val currentTask : LiveData<Task2>
        get() = _currentTask

And here the observer:

timerViewModel.currentTask.observe(viewLifecycleOwner) {
            updateUIText()
            updateCountdownUI()
            updateAnimation()
        }

Everytime I call the function to get the las saved task, the observers are called and everything works fine. But whenever I call the function to get a specific task by Id, the observers are not called.

I've set Logs all around and I've reached the conclusion that the LiveData is getting updated, but the observer is not triggered.

Here's the repo in case someone can have it a look. Thanks!!
https://github.com/arieldipietro/PomodoroTechnique

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怪我闹别瞎闹 2025-02-01 11:32:11

fragmentTimerfragmenthistory中,您已经创建了viewmodel使用其各自的fragments作为所有者的实例,这使他们可以观察到他们livedata仅由其实例触发。因此,现在,当您从fragmenthistory触发任务时,在fragmentTimer中不会观察到。

您需要使用sharedViewModel进行片段之间的数据,必须使用timerviewModel使用activity作为其所有者,那么您将能够从fragmentTimer观察。通过需要作为ViewModelProvider的构造函数中的所有者。

timerViewModel = ViewModelProvider(requireActivity(), viewModelFactory)[TimerViewModel::class.java]

您可以在此 codeLab tutorial 。

In FragmentTimer and FragmentHistory, you have created viewModel instances using their respective fragments as owners, which makes them to observe liveData which are triggered by their instances only. So, now when you trigger a task from FragmentHistory it isn't get observed in FragmentTimer.

You need to use SharedViewModel for passing data between fragments, you have to create object of TimerViewModel using activity as its owner, then you would be able to observe from FragmentTimer. Pass requireActivity() as the owner in ViewModelProvider's constructor.

timerViewModel = ViewModelProvider(requireActivity(), viewModelFactory)[TimerViewModel::class.java]

You can read more about it in this codelab tutorial.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文