我正在当前的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调用和/或任意数量的本地数据库对象?