我有一个必须在线和离线工作的Android应用。 正在从REST端点检索数据,并在CouchDBLite实例中本地缓存数据。 记录可以在离线和在线修改,因此我在我的对象上有一些属性,用于将对象设置为脏或删除。我不会详细介绍它,因为它不相关,但这种行为是要求的一部分。
我目前正在使用Retrofit 2和RxJava 1.x,我想出了一个工作函数来检索我需要的数据。
流程应遵循以下方案:
+------------------------------+
| |
| |
+--v---+ |
| | +-----------+ |
+-----> UI +---+----^+ DB getAll +----+
| | | +-----------+
++-----+ |
^ |
| ^
| +-----+------+
| | if canSync |
| +-----+------+
| | YES
| ^
| +------+--------+ +-----------+ +-----------+ +------------+ +----------+ +---------+
| | DB load DIRTY +----^+REST upload+---^+REST getAll+----^+set lastSync+---^+compare DB+----^+update DB|
| +---------------+ |DIRTY | +-----------+ +------------+ |lastUpdate| +----+----+
| +-----------+ +----------+ |
| |
| |
| +------v------------+
| YES |DB getAll |
+--------------------------------------------------------------------------------------------+returned 0 results?|
+-------------------+
以上流程基于以下规则:
现在我正在尝试简化检索数据的函数并最终使其成为通用函数,以便我可以根据需要获取的数据类型重用它。 我很难过,一只手真有帮助。
这是功能:
public Observable<List<MyTeam>> getAllMyTeam(final String idProfile) {
return teamLocalRepository.getAllMyTeam(idProfile)
.flatMapIterable(new Func1<List<MyTeam>, Iterable<MyTeam>>() {
@Override
public Iterable<MyTeam> call(List<MyTeam> myTeams) {
return myTeams;
}
})
.flatMap(new Func1<MyTeam, Observable<MyTeam>>() {
@Override
public Observable<MyTeam> call(final MyTeam team) {
return teamRemoteRepository.syncMyTeam(team);
}
})
.toList()
.flatMap(new Func1<List<MyTeam>, Observable<List<MyTeam>>>() {
@Override
public Observable<List<MyTeam>> call(List<MyTeam> myTeams) {
if (myTeams.size() == 0) {
// Return the data we fetch from the network
return teamRemoteRepository.getAllMyTeam(idProfile)
.map(new Func1<List<MyTeam>, List<MyTeam>>() {
@Override
public List<MyTeam> call(List<MyTeam> myTeams) {
return myTeams;
}
});
} else {
// Fire off a refresh from the network and ignore it
teamRemoteRepository.getAllMyTeam(idProfile)
.subscribeOn(Schedulers.io())
.subscribe();
// Return the cached data
return Observable.just(myTeams);
}
}
});
}
更新
我试着让它与泛型一起工作,因为我只想写两个方法,一个用于单个项目,一个用于项目列表。
我想出的项目列表如下,但我收到了很多unchecked
警告:
public Observable<List<T>> getAll(final Class<T> clazz, final Repository localRepo, final Repository remoteRepo, final String idProfile) {
return localRepo.getAll(idProfile)
.flatMapIterable(new Func1<List<T>, Iterable<T>>() {
@Override
public Iterable<T> call(List<T> items) {
return Collections.checkedList(items, clazz);
}
})
.flatMap(new Func1<T, Observable<T>>() {
@Override
public Observable<T> call(final T item) {
return remoteRepo.sync(item);
}
})
.toList()
.flatMap(new Func1<List<T>, Observable<List<T>>>() {
@Override
public Observable<List<T>> call(List<T> items) {
if (items.size() == 0) {
// Return the data we fetch from the network
return remoteRepo.getAll(idProfile)
.map(new Func1<List<T>, List<T>>() {
@Override
public List<T> call(List<T> items) {
return Collections.checkedList(items, clazz);
}
});
} else {
// Fire off a refresh from the network and ignore it
remoteRepo.getAll(idProfile)
.subscribeOn(Schedulers.io())
.subscribe();
// Return the cached data
return Observable.just(items);
}
}
});
}
我想我可以抑制该方法的未经检查的警告,但也许有更好的方法。
最重要的是,我无法生成T extends SomeBaseClass
,因为模型来自swagger-codegen
,看起来没有办法从自定义类继承模型,这会让事情变得更难,因为我{ {1}}方法需要检查模型的某些属性才能实际工作。