android–Room:来自Dao的LiveData会在每次更新时触发Observer.onChanged,即使LiveData值没有变化

android–Room:来自Dao的LiveData会在每次更新时触发Observer.onChanged,即使LiveData值没有变化,第1张

概述我发现Dao返回的LiveData会在DB中更新行时调用它的观察者,即使LiveData值显然没有改变.考虑类似以下示例的情况:示例实体@EntitypublicclassUser{publiclongid;publicStringname;//exampleforothervariablespublicDatelastActiveDateTime;}

我发现Dao返回的liveData会在DB中更新行时调用它的观察者,即使liveData值显然没有改变.

考虑类似以下示例的情况:

示例实体

@Entitypublic class User {    public long ID;    public String name;    // example for other variables    public Date lastActiveDateTime;}

示例道

@Daopublic interface UserDao {    // I am only interested in the user name    @query("SELECT name From User")    liveData<List<String>> getAllnamesOfUser();    @Update(onConflict = OnConflictStrategy.REPLACE)    voID updateUser(User user);}

某个地方在后台线程

UserDao userDao = //.... getting the daoUser user = // obtain from dao....user.lastActiveDateTime = new Date(); // no change to user.nameuserDao.updateUser(user);

UI中的某个地方

// omitted viewmodel for simplicityuserDao.getAllnamesOfUser().observe(this, new Observer<List<String>> {    @OverrIDe    public voID onChanged(@Nullable List<String> usernames) {        // this will be called whenever the background thread called updateUser.         // If user.name is not changed, it will be called with usernames         // with the same value again and again when lastActiveDateTime changed.    }});

在此示例中,ui仅对用户名感兴趣,因此liveData的查询仅包括名称字段.但是,即使只更新了其他字段,仍会在Dao Update上调用observer.onChanged.
(事实上​​,如果我没有对User实体进行任何更改并调用UserDao.updateUser,则仍会调用observer.onChanged)

这是Dao liveData在室内设计的行为吗?我是否有机会解决这个问题,以便只在更新所选字段时才会调用观察者?

编辑:我更改为使用以下查询将lastActiveDateTime值更新为评论建议中的Kuldip PaTel.仍然会调用用户名liveData的观察者.

@query("UPDATE User set lastActiveDateTime = :lastActiveDateTime where ID = :ID")voID updateLastActiveDateTime(Date lastActiveDateTime, int ID);

解决方法:

这种情况被称为观察者的误报通知.
请检查link中提到的第7点以避免此类问题.

Below example is written in kotlin but you can use its java version to get it work.

fun <T> liveData<T>.getdistinct(): liveData<T> {    val distinctliveData = MediatorliveData<T>()    distinctliveData.addSource(this, object : Observer<T> {        private var initialized = false        private var lastObj: T? = null        overrIDe fun onChanged(obj: T?) {            if (!initialized) {                initialized = true                lastObj = obj                distinctliveData.postValue(lastObj)            } else if ((obj == null && lastObj != null)                        || obj != lastObj) {                lastObj = obj                distinctliveData.postValue(lastObj)            }        }    })    return distinctliveData}
总结

以上是内存溢出为你收集整理的android – Room:来自Dao的LiveData会在每次更新时触发Observer.onChanged,即使LiveData值没有变化全部内容,希望文章能够帮你解决android – Room:来自Dao的LiveData会在每次更新时触发Observer.onChanged,即使LiveData值没有变化所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1099897.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存