Room & RxJava 的使用

原文链接

异步查询返回 LiveData 或 RxJava的 Maybe, Single or Flowable.

考虑如下UI场景:用户能查看和编辑用户名。用户信息被保存在数据库中。
为了从数据库中得到用户信息,我们使用如下查询方式:

@Query(“SELECT * FROM Users WHERE id = :userId”)
User getUserById(String userId);

这种方式有两个缺点:
1. 它是阻塞的、同步调用
2. 每次用户数据被修改,需要手动调用这个方法

Room可以观察数据库中的数据,并且通过RxJava的Maybe,Single,Flowable来执行异步查询。

通过在observeOn方法中设置Scheduler,可以决定让事件发生在哪个线程。
对于返回Maybe 或者 Single的查询,确保你在调用的subscribeOnScheduler不是AndroidSchedulers.mainThread()


为了使用Room 和 RxJava 2,需要在你的build.gradle 文件里添加如下依赖:

// 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);
  1. 数据库中没有该用户时,query 返回 no rows,Maybe complete.
  2. 当数据库中有一个用户时,Maybe 会触发onSuccess,然后complete.
  3. 如果在Maybe completed 之后user有更新,nothing happens.

Single

@Query(“SELECT * FROM Users WHERE id = :userId”)
Single<User> getUserById(String userId);
  1. 当数据库中没有该用户时,查询返回no rows,Single将触发onError(EmptyResultSetException.class).
  2. 当数据库中有一个用户时,Single将触发onSuccess.
  3. Single.onComplete被调用后user有更新,nothing happens,因为流已经完成了。

Flowable

@Query(“SELECT * FROM Users WHERE id = :userId”)
Flowable<User> getUserById(String userId);
  1. 当数据库中没有该用户时,查询返回no rows,Flowable不发射数据,既没有onNext,也没有onError.
  2. 当数据库中有一个用户时,Flowable将触发onNext.
  3. 每次用户数据有更新Flowable对象都会自动发出,允许你用最新的数据更新UI.

Testing

测试一个返回Maybe/Single/Flowable的查询和测试它的同步查询没有很大的不同。 在UserDaoTest,确保使用的是一个 in-memory 的数据库,因为当进程被杀死时,保存在这里的信息会被自动清除。

@RunWith(AndroidJUnit4.class)
public class UserDaoTest {private UsersDatabase mDatabase;
@Before
public void initDb() throws Exception {
    mDatabase = Room.inMemoryDatabaseBuilder(
                     InstrumentationRegistry.getContext(),
                     UsersDatabase.class)
            // allowing main thread queries, just for testing
            .allowMainThreadQueries()
            .build();
}

@After
public void closeDb() throws Exception {
    mDatabase.close();
}

添加InstantTaskExecutorRule规则到你的测试中,以确保Room立即执行所有的数据库操作。

@Rule
public InstantTaskExecutorRule instantTaskExecutorRule = 
                                      new InstantTaskExecutorRule();

让我们执行一个测试,订阅getUserById的发出,并检查确实在插入user时,Flowable发出正确的数据。

@Test
public void insertAndGetUserById() {
    // Given that we have a user in the data source
    mDatabase.userDao().insertUser(USER);
    // When subscribing to the emissions of user
    mDatabase.userDao()
             .getUserById(USER.getId())
             .test()
             // assertValue asserts that there was only one emission
             .assertValue(new Predicate<User>() {
                @Override
                public boolean test(User user) throws Exception {
                    // The emitted user is the expected one
                    return user.getId().equals(USER.getId()) &&
                      user.getUserName().equals(USER.getUserName());
                }
            });
}

That’s it! 如果你在应用中使用RxJava 2,请使数据库处于反应状态,并确保你的UI始终显示最新数据。在这里使用Room和RxJava查看示例应用程序

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值