根据Realm(https://realm.io/docs/java/latest/#rxjava)提供的文档,我有以下代码

public Observable<Foo> getFooById(String id) {

    realm = Realm.getInstance(realmConfiguration);

    return realm.where(Foo.class)
            .equalTo("id", id)
            .findFirstAsync()
            .asObservable()
            .filter(this::filterResult);
}

它可以按预期在App中运行,但是在进行测试时会变得有些棘手。我进行了以下测试(为了简单起见,对其进行了简化):
@Test
public void testRealmExample() {

    RealmConfiguration config = new RealmConfiguration.Builder(context)
            .name("test.realm")
            .inMemory()
            .build();

    DataManager dataManager = new DataManager(config);

    TestSubscriber<Foo> testSubscriber = new TestSubscriber<>();
    dataManager.getFoo("").observeOn(AndroidSchedulers.mainThread()).subscribe(testSubscriber);
    testSubscriber.assertNoErrors();
}

执行测试时,发生以下错误java.lang.IllegalStateException: Your Realm is opened from a thread without a Looper. Async queries need a Handler to send results of your query

为了解决这个问题,我在Realm GitHub page上阅读到,他们使用批注@UiThreadTest强制测试在UI线程上运行,据我所知,UI线程是一个looper线程,因此这应该可以解决我的问题。我补充说:
@Rule
public final UiThreadTestRule uiThreadTestRule = new UiThreadTestRule();

并更改了我的测试以包含注释
@Test
@UiThreadTest
public void testRealmExample() { ...}

这仍然会产生相同的异常。有人知道原因和解决方案吗?谢谢。

最佳答案

@UiThreadTest实际上并没有使您处于工作的Looper线程,而只是使您可以访问UI元素。我必须承认,我还没有真正研究过为何存在这种差异的细节。我们正在对Looper线程使用自定义规则(这也会清理Realm实例)。您可以在这里看到它,也可以以此为灵感:

https://github.com/realm/realm-java/blob/master/realm/realm-library/src/androidTest/java/io/realm/rule/RunInLooperThread.java

10-07 19:27
查看更多