【问题标题】:Data updating even when not being updated when using android room使用 android room 时数据更新,即使没有更新
【发布时间】:2020-07-28 05:42:03
【问题描述】:

我有一个 ArrayList,每当我使用 Room 更新数据库中的实时数据时都应该更新它。但是当我在更新我的列表之前和之后检查它的值时,之前的列表似乎已经更新,并且与我的列表在实际更新后显示类似的结果。这只发生在我更新子任务列时。

物品

@Entity(tableName = "items")
data class Item(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val title: String,
    val subtasks: ArrayList<Subtask> = ArrayList(),
    val notes: String = ""
) {
    fun getDetails(): String {
        var subtaskString = ""
        for (subtask in subtasks) {
            subtaskString += "(${subtask.title}: ${subtask.done}), "
        }
        return "id: ${id}\n" +
                "title: ${title}\n" +
                "subtasks: ${subtaskString}\n" +
                "notes: ${notes}\n"
    }
}

数据视图模型

val allItems: LiveData<List<Item>>
init {
    allItems= itemRepository.allItems
}

fun update(item: Item) = viewModelScope.launch(Dispatchers.IO) {
    itemRepository.update(item)
}

ItemRepository

val allItems: LiveData<List<Item>> = itemDao.getAllItems()

fun update(item: Item) {
    itemDao.update(item)
}

ItemDao

@Query("SELECT * FROM items")
fun getAllItems(): LiveData<List<Item>>

@Update
fun update(item: Item)

我的片段

val mList= ArrayList<Item>()
dataViewModel.allItems.observe(viewLifecycleOwner, Observer { items ->
    for (item in mList) {
        Log.i(TAG, "Before Updating: ${item.getDetails()}")
    }
    mList = ArrayList(items)  // update list values
    for (item in mList) {
        Log.i(TAG, "After Updating: ${item.getDetails()}")
    }
})

这是我更新项目的例子:

// current value of subtask in database is arrayListOf(Subtask("Old Subtask", false))
val updatedSubtasks = arrayListOf(Subtask("New Subtask", false))
val item = Item(
    id = id,
    title = title,
    subtasks = updatedSubtasks,
    notes = notes
)
dataViewModel.update(item)

当我更新一个项目时,只更改了子任务列表,并将数据记录在我的列表中,它会显示以下结果:

MyFragment: Before Updating: id: 0
                             title: My Title
                             subtasks: (New Subtask, false)
                             notes: Note

MyFragment: After Updating: id: 0
                            title: My Title
                            subtasks: (New Subtask, false)
                            notes: Note

而不是:

MyFragment: Before Updating: id: 0
                             title: My Title
                             subtasks: (Old Subtask, false)
                             notes: Note

MyFragment: After Updating: id: 0
                            title: My Title
                            subtasks: (New Subtask, false)
                            notes: Note

【问题讨论】:

    标签: android kotlin android-room android-livedata


    【解决方案1】:

    我不知道你什么时候在 ViewModel 中调用 update() 方法。但是,根据您的代码,我可以推断出以下内容,

    1. 当您在DataViewModel(希望来自MyFragment)中调用更新函数时,实体会获得更新,这可能会触发allItems LiveData。

    2. MyFragment 上的观察者在init 块被调用时第一次被触发。然后,您将在 ViewModel 中调用 update(item: Item),这将再次触发 LiveData,因此 MyFragment 中的观察者再次获得其值更新,这就是为什么您在 before update 日志和 after update log 中具有相同值的原因。

    3. 为了正确理解情况,

      mList = ArrayList(items) //the observer is called again here. 如果您正在更新这一行中的实体,那么观察者将再次被触发并使用相同的值。

    希望我澄清了情况。

    【讨论】:

    • 我不认为我的观察员在mList = ArrayList(items) 再次被调用,因为它没有改变我房间数据库中的任何内容
    • 哦,我以为你是从那里调用 ViewModel 中的 update() 。好吧,顺便说一句,您从哪里调用 ViewModel 中的更新。正如我所说,观察者将首先从 ViewModel 中的 init 块触发,然后如果我是对的,它将在调用更新时触发。当它被调用时,它只会在日志前后显示相同的值,因为你没有改变观察者的 lambda 块中的任何内容。
    • 上面的日志结果只是在我触发了我的更新功能之后,它不包括它第一次从 init 块调用的日志
    • 嘿,我想我知道这里发生了什么。由于循环是一个长时间运行的操作,因此 mList = ArrayList(items) 首先以某种方式分配。试试 Handler.postDelayed({mList.addAll(items)}, 1000)。试试这段代码,看看我是否正确。
    • 我已经尝试添加延迟,但仍然显示相同的结果。
    猜你喜欢
    • 1970-01-01
    • 2023-02-24
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    • 1970-01-01
    • 2018-02-25
    • 2023-01-12
    相关资源
    最近更新 更多