Dan*_*iev 3 android rx-java sqlbrite retrofit2
这是我的用例:
我正在开发一个通过REST API与服务器通信的应用程序,并将接收到的数据存储在SQLite数据库中(它将其用作某些类型的缓存).
当用户打开屏幕时,必须进行以下操作:
这与此处介绍的情况非常相似,但略有不同.
由于我使用的SQLBrite,数据库可观不会终止(因为有一个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);
})
})
Run Code Online (Sandbox Code Playgroud)
它似乎工作正常,但它似乎并不优雅和"正确".
你能否建议或指出一个资源,解释什么是处理这种情况的最佳方法?
如果你改变思维方式,问题的解决方案实际上非常简单和干净.我正在使用完全相同的数据交互(Retrofit + Sqlbrite),这个解决方案非常有效.
您需要做的是使用两个单独的可观察订阅,它们负责完全不同的过程.
Database -> View:这一个是用来连接您的View(Activity,Fragment或任何显示您的数据),以dB为单位的持久数据.您订阅了它ONCE for created View.dbObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(data -> {
displayData(data);
}, throwable -> {
handleError(throwable);
});
Run Code Online (Sandbox Code Playgroud)
API -> Database:另一个从api获取数据并将其保留在db中.每次要刷新数据库中的数据时,都会订阅它.apiObservable
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(data -> {
storeDataInDatabase(data);
}, throwable -> {
handleError(throwable);
});
Run Code Online (Sandbox Code Playgroud)
编辑:
您不希望将两个可观察对象"转换"为一个,纯粹是因为您已将其包含在您的问题中.两个可观察者的行为完全不同.
在observable从改造就像一个Single.它完成它需要做的事情,并完成(与onCompleted).
在observable从Sqlbrite是一个典型的Observable,它每次会发出一些特定的表的变化.从理论上讲,它应该在未来完成.
你可以解决这个问题,但它会带你走远,远离干净易读的代码.
如果你真的,真的需要公开一个observable,你可以隐藏这样一个事实,即你订阅数据库时实际上是从改装订阅了observable.
public void fetchRemoteData() {
apiObservable
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(data -> {
persistData(data);
}, throwable -> {
handleError(throwable);
});
}
Run Code Online (Sandbox Code Playgroud)
fetchRemoteData 订阅dbObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(() -> fetchRemoteData())
.subscribe(data -> {
displayData(data);
}, throwable -> {
handleError(throwable);
});
Run Code Online (Sandbox Code Playgroud)
我建议你真的考虑这一切.因为你迫使自己进入你需要一个可观察的位置的事实,可能会严重限制你.我相信这将是迫使你在未来改变你的概念的确切事情,而不是保护你免受变化本身.
| 归档时间: |
|
| 查看次数: |
531 次 |
| 最近记录: |