这是我的用例:
我正在开发一个通过REST API与服务器通信的应用程序,并将接收到的数据存储在SQLite数据库中(它将其用作某些类型的缓存).
当用户打开屏幕时,必须进行以下操作:
如果可用,数据将从DB加载.
该应用程序调用API来刷新数据.
API调用的结果将持久保存到DB.
截获数据更改通知时,将从数据库重新加载数据.
这与此处介绍的情况非常相似,但略有不同.
由于我使用的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); }) })
它似乎工作正常,但它似乎并不优雅和"正确".
你能否建议或指出一个资源,解释什么是处理这种情况的最佳方法?
如果你改变思维方式,问题的解决方案实际上非常简单和干净.我正在使用完全相同的数据交互(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); });
API
->
Database
:另一个从api获取数据并将其保留在db中.每次要刷新数据库中的数据时,都会订阅它.
apiObservable .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .subscribe(data -> { storeDataInDatabase(data); }, throwable -> { handleError(throwable); });
编辑:
您不希望将两个可观察对象"转换"为一个,纯粹是因为您已将其包含在您的问题中.两个可观察者的行为完全不同.
在observable
从改造就像一个Single
.它完成它需要做的事情,并完成(与onCompleted
).
在observable
从Sqlbrite是一个典型的Observable
,它每次会发出一些特定的表的变化.从理论上讲,它应该在未来完成.
你可以解决这个问题,但它会带你走远,远离干净易读的代码.
如果你真的,真的需要公开一个observable
,你可以隐藏这样一个事实,即你订阅数据库时实际上是从改装订阅了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); });
我建议你真的考虑这一切.因为你迫使自己进入你需要一个可观察的位置的事实,可能会严重限制你.我相信这将是迫使你在未来改变你的概念的确切事情,而不是保护你免受变化本身.