使用Android Room时即使不更新数据也能更新

时间:2020-07-28 05:42:03

标签: android kotlin android-room android-livedata

我有一个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"
    }
}

DataViewModel

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)

MyFragment

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

1 个答案:

答案 0 :(得分:0)

我不知道您何时在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. 如果您要在此行中更新实体,则观察者将再次使用相同的值触发。

希望我已经澄清了情况。