这里是我的用例:
我正在开发一个应用程序,它通过REST与服务器通信,并将接收到的数据存储在SQLite数据库中(它用作某种缓存)。
当用户打开屏幕时,必须发生以下情况:
这与这里的情况非常相似,但差别很小。
由于我使用的是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);
})
})它似乎工作正常,但它只是看上去不优雅和“正确”。
你能给我建议或者指点一个资源来解释什么是处理这种情况的最好方法吗?
发布于 2017-01-10 15:29:25
如果你稍微改变一下思维方式,你的问题的解决方案实际上是非常简单和干净的。我使用的是完全相同的数据交互(Retrofit + Sqlbrite),这个解决方案工作得很好。
您需要做的是使用两个单独的可观察订阅,它们处理完全不同的过程。
Database -> View:这个用于将您的View (Activity、Fragment或其他显示数据的内容)附加到db中的持久化数据。您只需为创建的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,您可以只需隐藏这一事实,即在订阅数据库时,您实际上是在订阅可观察到的可观察到的对象。
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);
});我建议你好好想想。因为你强迫自己进入一个你需要一个可以观察到的位置,这可能会严重地限制你。我相信这会迫使你在未来改变你的观念,而不是保护你不受改变本身的影响。
https://stackoverflow.com/questions/41572091
复制相似问题