当前位置:  开发笔记 > 数据库 > 正文

使用SQLBrite + Retrofit刷新数据

如何解决《使用SQLBrite+Retrofit刷新数据》经验,为你挑选了1个好方法。

这是我的用例:

我正在开发一个通过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);
            })
})

它似乎工作正常,但它似乎并不优雅和"正确".

你能否建议或指出一个资源,解释什么是处理这种情况的最佳方法?



1> Bartek Lipin..:

如果你改变思维方式,问题的解决方案实际上非常简单和干净.我正在使用完全相同的数据交互(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);
        });

我建议你真的考虑这一切.因为你迫使自己进入你需要一个可观察的位置的事实,可能会严重限制你.我相信这将是迫使你在未来改变你的概念的确切事情,而不是保护你免受变化本身.

推荐阅读
mobiledu2402851373
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有