首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用SQLBrite + Retrofit刷新数据

使用SQLBrite + Retrofit刷新数据
EN

Stack Overflow用户
提问于 2017-01-10 15:13:33
回答 1查看 585关注 0票数 3

这里是我的用例:

我正在开发一个应用程序,它通过REST与服务器通信,并将接收到的数据存储在SQLite数据库中(它用作某种缓存)。

当用户打开屏幕时,必须发生以下情况:

  1. 数据是从DB加载的,如果可用的话。
  2. 应用程序调用API来刷新数据。
  3. API调用的结果将持久化到DB。
  4. 当截获数据更改通知时,将从DB重新加载数据。

这与这里的情况非常相似,但差别很小。

由于我使用的是SQLBrite,所以DB可观测值不会终止(因为在那里注册了一个ContentObserver,它将新的数据推入流中),所以concatmerge等方法将无法工作。

目前,我已经使用以下方法解决了这一问题:

代码语言:javascript
复制
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);
            })
})

它似乎工作正常,但它只是看上去不优雅和“正确”。

你能给我建议或者指点一个资源来解释什么是处理这种情况的最好方法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-10 15:29:25

如果你稍微改变一下思维方式,你的问题的解决方案实际上是非常简单和干净的。我使用的是完全相同的数据交互(Retrofit + Sqlbrite),这个解决方案工作得很好。

您需要做的是使用两个单独的可观察订阅,它们处理完全不同的过程。

  1. Database -> View:这个用于将您的View (ActivityFragment或其他显示数据的内容)附加到db中的持久化数据。您只需为创建的View订阅一次。

代码语言:javascript
复制
dbObservable
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(data -> {
            displayData(data);
        }, throwable -> {
            handleError(throwable);
        });
  1. API -> Database:另一个从api获取数据并将其保存在db中。每次要刷新数据库中的数据时,都要订阅它。

代码语言:javascript
复制
apiObservable
        .subscribeOn(Schedulers.io())
        .observeOn(Schedulers.io())
        .subscribe(data -> {
           storeDataInDatabase(data);
        }, throwable -> {
            handleError(throwable);
        });

编辑:

你不想把两个可观察到的物体“转换”成一个,纯粹是因为你在问题中包含了这个原因。这两种观察仪器的行为完全不同。

来自重新装修的observable表现得像一个Single。它完成了它需要做的事情,并完成了(使用onCompleted)。

来自Sqlbrite的observable是一个典型的Observable,每当特定的表发生更改时,它都会发出一些内容。从理论上讲,它应该在未来完成。

Ofc可以解决这一差异,但它将使您远离一个干净、易读的代码。

如果您确实需要公开一个observable,您可以只需隐藏这一事实,即在订阅数据库时,您实际上是在订阅可观察到的可观察到的对象。

  1. 将Api订阅包装在一个方法中:

代码语言:javascript
复制
public void fetchRemoteData() {
    apiObservable
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.io())
            .subscribe(data -> {
                persistData(data);
            }, throwable -> {
                handleError(throwable);
            });
}
  1. 订阅fetchRemoteData

代码语言:javascript
复制
dbObservable
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .doOnSubscribe(() -> fetchRemoteData())
        .subscribe(data -> {
            displayData(data);
        }, throwable -> {
            handleError(throwable);
        });

我建议你好好想想。因为你强迫自己进入一个你需要一个可以观察到的位置,这可能会严重地限制你。我相信这会迫使你在未来改变你的观念,而不是保护你不受改变本身的影响。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41572091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档