这是我的用例:
我正在开发一个应用程序,该应用程序通过REST API与服务器通信,并将接收到的数据存储在SQLite数据库中(它将其用作某种缓存)。
当用户打开屏幕时,必须发生以下情况:
- 数据从数据库加载(如果可用)
- 应用程序调用API来刷新数据
- API调用的结果被持久化到DB
- 当数据更改通知被截获时,数据将从数据库中重新加载
这与这里介绍的情况非常相似,但略有不同。
由于我使用的是SQLBrite,所以DB的可观测性不会终止(因为那里注册了一个ContentObserver
,它会将新数据推送到流中),所以像concat
、merge
等方法将不起作用。
目前,我已经使用以下方法解决了这个问题:
Observable.create(subscriber -> {
dbObservable.subscribe(subscriber);
apiObservable
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(
(data) -> {
try {
persistData(data);
} catch (Throwable t) {
Exceptions.throwOrReport(t, subscriber);
}
},
(throwable) -> {
Exceptions.throwOrReport(throwable, subscriber);
})
})
它看起来工作正常,但看起来并不优雅和"正确"。
你能建议我或给我指一个资源来解释处理这种情况的最佳方法吗?
如果你稍微改变一下思维方式,问题的解决方案实际上是非常简单和干净的。我使用完全相同的数据交互(改装+Sqlbrite),这个解决方案非常有效。
您要做的是使用两个独立的可观察订阅,它们负责处理完全不同的过程。
Database
->
View
:这个用于将您的View
(Activity
、Fragment
或任何显示数据的内容)附加到数据库中的持久数据。您为创建的View
订阅一次
dbObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(data -> {
displayData(data);
}, throwable -> {
handleError(throwable);
});
API
->
Database
:另一个从api获取数据并将其持久化在db中。每当您想刷新数据库中的数据时,都可以订阅它
apiObservable
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(data -> {
storeDataInDatabase(data);
}, throwable -> {
handleError(throwable);
});
编辑:
你不想把两个可观察性"转化"为一个,纯粹是因为你在问题中包含了这个原因。两种可观察器的作用完全不同。
改装后的observable
与Single
类似。它做它需要做的事情,并完成(使用onCompleted
)。
Sqlbrite中的observable
是一个典型的Observable
,每当特定的表发生变化时,它就会发出一些东西。理论上它应该在未来完成。
Ofc你可以解决这个差异,但它会让你远离干净易读的代码。
如果您真的、真的需要公开一个observable
,那么在订阅数据库时,您可以隐藏您实际上订阅了来自改装的可观察对象这一事实。
- 用一种方法包装Api订阅:
public void fetchRemoteData() {
apiObservable
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(data -> {
persistData(data);
}, throwable -> {
handleError(throwable);
});
}
fetchRemoteData
订阅
dbObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(() -> fetchRemoteData())
.subscribe(data -> {
displayData(data);
}, throwable -> {
handleError(throwable);
});
我建议你认真考虑一下。因为事实上,你把自己逼到了需要一个可观察的位置,这可能会严重限制你。我相信,这正是迫使你在未来改变观念的事情,而不是保护你免受改变本身的影响。