Realm + Retrofit + Rxjava

3

我正在尝试通过RxJava Observable将我从Retro中解析的对象保存到Realm中。

目前我有一个API调用:

fetchCatalogData().subscribeOn(Schedulers.io())
                  .subscribe(data ->
                       saveToRealm();
                  )

这不起作用,因为我要么在不同的线程上使用realm,要么scheduler.io没有looper。

我不确定如何最好地使用retrofit、realm和rxjava。我希望能够在数据从retrofit到达时保存所有数据,然后在以后访问它们。


1
我找到了另一篇帖子,其中有一个可行的答案。https://stackoverflow.com/questions/35897737/how-to-combine-retrofit-2-with-realm-and-rxjava - jhysum
3个回答

3
你可以利用一个非常好的库将所有内容结合起来。 https://github.com/FabianTerhorst/ApiClient “一个易于使用的 API 客户端,结合了 Retrofit、Realm、Gson、Rxjava 和 Retrolambda 的强大功能,是 Java 和 Android 的易于使用的库。”

3

实际上很简单,你只需要拥有两个不同的流——一个用于下载,另一个用于显示数据。

我假设fetchCatalogData()通过Retrofit返回数据,因此是未经管理的对象。

fetchCatalogData()
.subscribeOn(Schedulers.io())
.subscribe(data ->
     saveToRealm(data);
)

在这种情况下,只要saveToRealm()打开一个特定于线程的Realm实例,就可以正常工作:
private void saveToRealm(CatalogData data) {
    try(Realm r = Realm.getDefaultInstance()) {
        r.executeTransaction((realm) -> {
            realm.insertOrUpdate(data);
        });
    }
}

这将允许您在后台线程上创建一个Realm(它将自动关闭),并将其持久化到Realm中。
对于UI线程,您将为CatalogData创建一个查询,并通过Realm对RxJava的支持,将 RealmChangeListener 附加到结果集,并接收一个“热Observable”,每当基础表更改时,您都会获得结果。
Subscription showCatalog = realm.where(CatalogData.class)
                                .findAllAsync()
                                .filter(RealmResults::isLoaded)
                                .filter(RealmResults::isValid) 
                                .subscribe((results) -> {
                                    adapter.updateData(results);
                                });

1
Realm可以与Retrofit 1.*和2.*直接配合使用,但请注意Retrofit不会自动将对象添加到Realm中,您需要使用realm.copyToRealm()realm.copyToRealmOrUpdate()方法手动添加它们。保留html标签。
GitHubService service = restAdapter.create(GitHubService.class);
List<Repo> repos = service.listRepos("octocat");

// Copy elements from Retrofit to Realm to persist them.
realm.beginTransaction();
List<Repo> realmRepos = realm.copyToRealmOrUpdate(repos);
realm.commitTransaction();

此外,Realm对RxJava提供了一流的支持,这意味着以下Realm类可以作为Observable暴露出来:RealmRealmResultsRealmObjectDynamicRealmDynamicRealmObject
// Combining Realm, Retrofit and RxJava (Using Retrolambda syntax for brevity)
// Load all persons and merge them with their latest stats from GitHub (if they have any)
Realm realm = Realm.getDefaultInstance();
GitHubService api = retrofit.create(GitHubService.class);
realm.where(Person.class).isNotNull("username").findAllAsync().asObservable()
.filter(persons.isLoaded)
.flatMap(persons -> Observable.from(persons))
.flatMap(person -> api.user(person.getGithubUserName())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(user -> showUser(user));

这是官方的 Realm 文档

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接