【问题标题】:How does LiveData know when data is changed in Room Database?LiveData 如何知道房间数据库中的数据何时更改?
【发布时间】:2018-07-07 21:48:27
【问题描述】:

我正在android中学习Mvvm模式,但我不明白一件事。 Live Data 如何知道房间数据库中的数据何时发生变化?我有这个代码:

片段:

 newUserViewModel.getListItemById(itemId).observe(this, new Observer<User>() {
        @Override
        public void onChanged(@Nullable User user) {
            tv.setText(user.getName());
        }
    });

查看模型:

 public LiveData<User> getListItemById(String itemId){       
    return repository.getListItem(itemId);
}

存储库:

 public LiveData<User> getListItem(String itemId){
    return userDao.getUSerByID(itemId);
}

道:

@Query("SELECT * FROM User WHERE itemId = :itemId")
LiveData<User> getUSerByID(String itemId);// When this query gets executed and how live Data knows that our Table is changed?

假设我们在数据库中插入了新用户。当我们的数据库中有新数据时,@Query("SELECT * FROM User WHERE itemId = :itemId") 何时执行?)以及 LiveData 如何知道我们在表中有新用户并回调观察者所有者数据已更改?

【问题讨论】:

  • 因为在内部,Room 存储了观察者,并在 INSERT 语句之后通过 LiveData 通知他们
  • 好的,现在说得通了,非常感谢您的帮助。您可以将此评论作为答案,以便我检查。
  • 您能否澄清一下“通过 LiveData 通知他们”的工作流程?那么 INSERT 是如何完成这种情况下 LiveData 通知 Observer 的呢?有一些回调方法?在通知观察者调用之后:newUserViewModel.getListItemById(itemId)
  • 顺便说一下,根据文档,您不应该从视图模型中调用 repository.getListItem 。 developer.android.com/topic/libraries/architecture/livedata

标签: android mvvm


【解决方案1】:

Android Room code潜水之后,我发现了一些事情:

  1. 房间注释处理器使用javapoet库从房间注释(@Query@Insert...)生成代码

  2. 根据查询的结果类型 (QueryMethodProcessor),它使用“绑定器”或另一个。对于LiveData,它使用LiveDataQueryResultBinder

  3. LiveDataQueryResultBinder 生成一个LiveData 类,其中包含_observer 类型的InvalidationTracker.Observer 字段,负责监听数据库变化。

然后,基本上,当数据库发生任何变化时,LiveData 将失效并通知客户端(您的存储库)。

【讨论】:

  • 对一些条件查询来说不是很有效吗?例如,我只是拉一个子集来填充我的 ListView,但是每当插入任何不相关的数据时,我的观察 LiveData 就会失效,然后 ListView 将被重新填充。
  • 但是它怎么知道有更新呢?它使用轮询吗?
【解决方案2】:

向您的 Dao 添加一个仅用于通知的查询,例如:

@Query("SELECT * FROM my_table")
public LiveData<List<MyItem>> changeNotif();

然后在你的活动中听这样的变化:

LiveData<List<MyItem>> items = AppDatabase.getAppDatabase().itemDao().changeNotif();
items.observe(this, new Observer<List<MyItem>>() {
    @Override
    public void onChanged(List<MyItem> myItems) {
    }
});

【讨论】:

  • 这根本没有回答问题。问题不是询问 API 的使用,而是询问它在内部是如何工作的
猜你喜欢
  • 1970-01-01
  • 2020-02-06
  • 2018-04-14
  • 1970-01-01
  • 2020-06-24
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多