【问题标题】:Room and Livedata false positive notificationRoom 和 Livedata 误报通知
【发布时间】:2019-05-14 12:21:36
【问题描述】:
我正在观察来自聊天屏幕活动的以下查询:
@Query("SELECT * FROM messages where conversationId = :conversationId order by id desc")
LiveData<List<Message>> getMessagesByConversationId(long conversationId);
因此,如果此对话 id 收到消息,我的观察者将收到通知。但问题是我检测到我的观察者正在通知,即使一条消息来自另一个对话 ID。我想这对于大表来说是一个大问题,因为行太多,每次当消息到达另一个对话时我的查询都会运行。我认为这是无效的。
我怎样才能更有效地完成这个过程?
【问题讨论】:
标签:
java
android-room
android-livedata
【解决方案1】:
Room只知道表被修改了,不知道为什么和什么发生了变化。因此,在重新查询后,查询结果由LiveData 或Flowable 发出。
由于 Room 没有在内存中保存任何数据并且不能假设对象具有equals(),因此它无法判断这是否是相同的数据。
您需要确保您的 DAO 过滤排放物并且只对不同的对象作出反应。
如果使用Flowables 实现可观察查询,请使用Flowable#distinctUntilChanged。
@Dao
abstract class UserDao : BaseDao<User>() {
/**
* Get a user by id.
* @return the user from the table with a specific id.
*/
@Query(“SELECT * FROM Users WHERE userid = :id”)
protected abstract fun getUserById(id: String): Flowable<User>
fun getDistinctUserById(id: String): Flowable<User> = getUserById(id)
.distinctUntilChanged()
}
在此处查找更多实施细节:7 Pro-tips for Room
distinctUntilChanged()
返回一个 Flowable,它根据Object.equals(Object) 比较发出源发布者发出的所有与其直接前辈不同的项目。
【解决方案2】:
您可以使用分页中使用的逻辑来检索所有数据..
@Query("SELECT * FROM messages where conversationId = :conversationId order by id desc limit :numberOfData :pageNumber")
LiveData<List<Message>> getMessagesByConversationId(long conversationId,long numberOfData,long pageNum);
在 getMessagesByConversationId 中
你可以使用
int totalNumberOfRows=select count(*) from messages where conversationId = :conversationId ;(logic to get the number of data in query)
pageNumber=totalNumberOfRows-(numberOfData *(pageNum-1));
您将更快地获得最少的数据..
快乐编码