Android Room 使用说明
文章目录
基本的使用说明可以直接看官方网站,比较清晰了:
https://developer.android.com/training/data-storage/room
重点主要记录下和 RxJava 结合使用上的问题。
更少的重复代码,编译时检查的SQL查询,除此之外还有异步功能和可观察的查询-听起来是不是很牛?有了 Room,这些都成为可能。异步查询返回 LiveData 或者 RxJava 的 Maybe, Single 或者 Flowable。
它们都是可观察的查询,可以让你在在数据变更的时候自动获得更新,以便确保UI上反应的是数据库的最新数据。如果你已经在app中使用了RxJava 2 ,那么把 Room 和 Maybe, Single 以及 Flowable 一起使用应该会非常轻松。
我们简单举个例子:
为了从数据库获得user,我们可以在UserDao中编写下面的查询:
@Query(“SELECT * FROM Users WHERE id = :userId”)
User getUserById(String userId);
这种方法有两个缺点:
- 它是一个阻塞式的,同步的调用
- 每次数据变更的时候我们都需要手动调用一次这个方法
Room 提供了对数据库中数据进行观察的选项,并通过 RxJava 的 Maybe, Single 和 Flowable 对象来执行异步查询。
要让Room支持RxJava 2,在 build.gradle 文件添加如下的 dependencies :
// RxJava support for Room
implementation “android.arch.persistence.room:rxjava2:1.0.0-alpha5”
// Testing support
androidTestImplementation “android.arch.core:core-testing:1.0.0-alpha5”
Maybe
@Query("SELECT * FROM Users WHERE id = :userId")
Maybe<User> getUserById(String userId);
Maybe 可能发生的情况如下:
- 当数据库中没有 user,Maybe 调用 complete;
- 当数据库中有一个user时,Maybe将触发 onSuccess 并调用 complete;
- 如果在 Maybe 的complete调用之后user被更新,什么也不会发生。
Single
@Query("SELECT * FROM Users WHERE id = :userId")
Single<User> getUserById(String userId);
Single 可能发生情况如下:
- 当数据库中没有user,查询没有返回行时,Single 触发 onError(EmptyResultSetException.class);
- 当数据库中有一个user时, Single 触发 onSuccess;
- 如果在 Single.onComplete 调用之后user被更新,什么也不会发生;
Flowable
@Query("SELECT * FROM Users WHERE id = :userId")
Flowable<User> getUserById(String userId);
Flowable 可能发生情况如下:
- 当数据库中没有user,查询没有返回行时,Flowable不会发射,也不会触发onNext, 或者 onError;
- 当数据库中有一个user时,Flowable会触发onNext;
- 每当user更新之后,Flowable将自动发射,这样你就可以根据最新的数据来更新UI;
tips:这里的getUserById返回的是Flowable,如果查询没有结果的话,什么信息也收不到,这在实际开发中是很蛋疼的。但是如果我们把返回类型改成Flowable<List>的话,如果查询没有结果是可以得到一个空list的。作者在回复中讲到之所以第一种情况没有通知是因为,在实现的过程中遇到了bug。不过我个人认为要解决这个问题应该不难吧。
参考:https://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2017/0726/8268.html
文章作者 Brook
上次更新 2022-05-17