为什么我的SharedViewModel的emptyDatabase观察者会优先执行?
根本原因
SharedViewModel中的emptyDatabase这个MutableLiveData初始化时默认值被设为了true,而LiveData存在粘性回调特性:当给已有值的LiveData注册观察者时,会立刻将当前存储的值回调给观察者。- 你在Fragment中先注册了
getAllData的观察者,但getAllData是Room返回的LiveData,数据库查询属于IO操作,即使使用挂起函数实现,首次查询返回数据也有延迟,不会立刻触发回调。 - 你后续注册
emptyDatabase的观察者时,它已经持有初始值true,会立刻触发回调执行showEmptyDatabaseViews(true),把原本不可见的空态图片改成可见;直到数据库查询完成返回数据,才会触发getAllData的回调更新emptyDatabase的值,隐藏空态、显示列表,就出现了你看到的先闪空态再出列表的问题。
可行解决方案
方案1(改造成本最低)
修改emptyDatabase的初始值为null,空态显示逻辑里判断只有值为非null的时候才执行可见性更新,避免初始值的干扰:
// SharedViewModel中修改初始化逻辑 val emptyDatabase: MutableLiveData<Boolean?> = MutableLiveData(null) // Fragment中回调逻辑修改 mSharedViewModel.emptyDatabase.observe(viewLifecycleOwner, Observer { isEmpty -> isEmpty ?: return@Observer showEmptyDatabaseViews(isEmpty) })
方案2
调整LiveData观察顺序,先注册emptyDatabase的观察者,再注册getAllData的观察者,同时修改showEmptyDatabaseViews逻辑,首次空态显示延迟到拿到第一份数据库查询结果后再执行。
方案3
改用非粘性的LiveData实现(比如SingleLiveEvent),避免初始值的自动回调。
内容的提问来源于stack exchange,提问作者Jaydip Solanki
相关产品推荐
相关产品推荐

