通过纯RxJava和翻新来刷新Android本地数据库的“最佳实践”

时间:2018-08-16 09:15:26

标签: android retrofit2 rx-java2

我正在当前的Android项目中试用Retrofit,RxJava和Android LiveData。

我通过RESTful API从远程服务器获取所有数据,并将这些数据存储在本地Realm数据库中。

对于每种类型的数据,我都有以下模式。

1)。检查本地数据库中是否已经存在数据。

2)。当数据确实存在于本地数据库中时,我将数据库对象检索并转换为我的UI模型对象,然后将UI数据列表发布到LiveData观察器中。

3)。否则,当在本地I数据库中找不到数据时,我调出远程服务器,以json的形式检索数据并将其保存在本地数据库中。最后,我检索数据库对象并将其转换为我的UI模型对象,然后将UI数据列表发布到LiveData观察器中。

当前,这是我在ViewModel存储库中拥有的有效解决方案:-

 public LiveData<List<DataUI>> getData() {

        final Disposable disposable = Single.just(RxJavaDatabaseController.dataExist())
                .subscribeOn(Schedulers.io())
                .flatMap((Function<Single<Boolean>, SingleSource<List<DataDO>>>) exist -> {
                    final Boolean existing = exist.blockingGet();

                    if (existing) {
                    } else {
                        RxJavaNetworkController.getData(true).doOnSuccess(new Consumer<Response<String>>() {
                            @Override
                            public void accept(final Response<String> response) throws Exception {
                                RxJavaDatabaseController.persistDataJson(response.body());
                            }
                        }).subscribe();
                    }

                    return RxJavaDatabaseController.fetchData();
                })
                .doOnSuccess(dataDOs -> {
                    final List<DataUI> dataUIs = new ArrayList<>();

                    if (dataDOs == null || dataDOs.isEmpty()) {
                        DATA.postValue(dataUIs);
                        return;
                    }

                    for (final DataDO dataDO : dataDOs) {
                        final DataUI dataUI = new DataUI();
                        dataUI.setActive(true);
                        dataUI.setId(dataDO.getId());
                        dataUI.setName(dataDO.getName());
                        dataUIs.add(dataUI);
                    }

                    DATA.postValue(dataUIs);
                })
                .subscribe();

        compositeDisposable.add(disposable);


        return DATA;
    }

我的dataExist()方法类似于:-

public static Single<Boolean> dataExist() {
        try (final Realm realm = Realm.getInstance(REALM_CONFIGURATION.LOCAL_DB.getRealmConfiguration())) {
            final DataDO dataDO = realm.where(DataDO.class).findFirst();
            if (dataDO == null) {
                return Single.create(emitter -> emitter.onSuccess(false));
            }
        }

        return Single.create(emitter -> emitter.onSuccess(true));
    }

我的提取数据方法类似于:-

/**
 * @return
 */
public static Single<List<DataDO>> fetchData() {
    try (final Realm realm = Realm.getInstance(REALM_CONFIGURATION.LOCAL_DB.getRealmConfiguration())) {
        final RealmResults<DataDO> dataDOs = realm.where(DataDO.class).findAll();
        final List<DataDO> datas = realm.copyFromRealm(dataDOs);
        return Single.create(emitter -> emitter.onSuccess(datas));
    }
}

我的网络getData方法类似于:-

@Override
public Single<Response<String>> getDataJson(@NonNull final String authenticationToken, @NonNull final Boolean isActive) {
    return service.getDataJson(authenticationToken, isActive);
}

但是我的持久数据方法类似于:-

/**
 * @param rawJson
 */
public static void persistDataJson(final String rawJson) {
    if (TextUtils.isEmpty(rawJson)) {
        Log.e(TAG, "persistDataJson() called with empty rawJson.");
        return;
    }

    try (final Realm realm = Realm.getInstance(REALM_CONFIGURATION.LOCAL_DB.getRealmConfiguration())) {
        realm.executeTransaction(createAllRealm -> createAllRealm.createAllFromJson(DataDO.class, json));
    }
}

显然,我需要在此解决方案中添加错误处理。

我主要担心的是,这种“样式”或“模式”并不是用于更复杂的数据检索方案(例如,必须依次调用多个API)的良好基础。

我的持久数据方法还应该返回一个Completable,以便它可以为Rx的“流程”做出贡献。

如何改进/重构上述RxJava代码以应对任意数量的API调用和/或任意数量的本地数据库对象?

0 个答案:

没有答案