RxJava/Reformation2/Java-NetworkBoundResource未按预期工作
我有一些有线问题。当我第一次订阅时,它进行网络调用并将数据保存到数据库中,但是RxJava/Reformation2/Java-NetworkBoundResource未按预期工作,java,android,rx-java,rx-java2,rx-android,Java,Android,Rx Java,Rx Java2,Rx Android,我有一些有线问题。当我第一次订阅时,它进行网络调用并将数据保存到数据库中,但是loadFromDb()从未执行,并且没有抛出任何错误 为什么会发生这种情况 Flowable<Resource<List<List<DataSource>>>> getBoundResource(List<String> parentId) { return new RxNetworkBoundResource<List<List
loadFromDb()
从未执行,并且没有抛出任何错误
为什么会发生这种情况
Flowable<Resource<List<List<DataSource>>>> getBoundResource(List<String> parentId) {
return new RxNetworkBoundResource<List<List<DataSource>>,
ContainerResponse>() {
@Override
void saveCallResult(@NonNull List<ContainerResponse> data) {
for (ContainerResponse item : data) {
// Saves data to database
List<DataSource> items = item.items;
containerDao.insert(items);
}
}
@Override
protected Flowable<List<List<DataSource>>> loadFromDb() {
return Flowable.just(parentId).flatMapIterable(d -> d)
.flatMap(s -> containerDao.loadContainerByParentIdRx(s))
.distinct()
.doOnNext(data -> {
// I am able to get data here
})
.toList() // I'm not able to get data after toList()
.toFlowable()
.doOnNext(data -> {
// Nothing here
});
}
@Override
protected Flowable<List<Response<ContainerResponse>>> createCall() {
String baseUrl =
MyApp.getApplication().getSharedConfig().getBaseUrl();
return Flowable.just(parentId).flatMapIterable(data -> data).flatMap(s -> {
String url = baseUrl + "?limit=30&offset=0&parent=" + s;
return Flowable.zip(Flowable.just(s),webservice.getContainersBoundRx(url),
(s1, response) -> {
if (response.body() == null) {
return response;
}
for (DataSource container : response.body().items) {
container.parentId = s1;
}
return response;
}).toList().toFlowable();
});
}
@Override
protected boolean shouldFetch() {
return false;
}
}.asFlowable();
NetworkboundResource
class:
public abstract class RxNetworkBoundResource<ResultType, RequestType> {
private final String TAG = RxNetworkBoundResource.class.getSimpleName();
private Flowable<Resource<ResultType>> result;
RxNetworkBoundResource() {
// Lazy db observable.
Flowable<ResultType> dbObservable =
Flowable.defer(() -> loadFromDb().subscribeOn(Schedulers.computation()));
// Lazy network observable.
Flowable<ResultType> networkObservable = Flowable.defer(() ->
createCall()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.doOnNext(request -> {
if (request.get(0).isSuccessful()) {
saveCallResult(processResponse(request));
} else {
processInternalError(request);
}
})
.onErrorReturn(throwable -> {
throw Exceptions.propagate(throwable);
})
.flatMap(__ -> loadFromDb())
);
result = shouldFetch()
? networkObservable
.map(Resource::success)
.onErrorReturn(t -> Resource.error(t.getMessage(), null))
.observeOn(AndroidSchedulers.mainThread())
: dbObservable
.map(Resource::success)
.onErrorReturn(t -> Resource.error(t.getMessage(), null))
.observeOn(AndroidSchedulers.mainThread())
;
}
Flowable<Resource<ResultType>> asFlowable() {
return result;
}
private List<RequestType> processResponse(List<Response<RequestType>> response) {
List<RequestType> list = new ArrayList<>();
for (Response<RequestType> data : response) {
list.add(data.body());
}
return list;
}
private void processInternalError(List<Response<RequestType>> response) throws java.io.IOException {
for (Response<RequestType> data : response) {
if (data.errorBody() != null) {
String error = data.errorBody().string();
throw Exceptions.propagate(new Throwable(data.code() + ": " + error));
}
}
}
abstract void saveCallResult(@NonNull List<RequestType> item);
abstract Flowable<ResultType> loadFromDb();
abstract Flowable<List<Response<RequestType>>> createCall();
abstract boolean shouldFetch();
}
公共抽象类RxNetworkBoundResource{
私有最终字符串标记=RxNetworkBoundResource.class.getSimpleName();
私人流动结果;
RxNetworkBoundResource(){
//可以观察到。
可流动可观测=
Flowable.defer(()->loadFromDb().subscribeOn(Schedulers.computation());
//可观察的惰性网络。
可流动网络可观察=可流动。延迟(()->
createCall()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.computation())
.doOnNext(请求->{
if(request.get(0.issusccessful()){
saveCallResult(processResponse(request));
}否则{
processInternalError(请求);
}
})
.onErrorReturn(可丢弃->{
抛出异常。传播(可丢弃);
})
.flatMap(\uu->loadFromDb())
);
结果=shouldFetch()
?网络可观察
.map(资源::成功)
.OneErrorReturn(t->Resource.error(t.getMessage(),null))
.observeOn(AndroidSchedulers.mainThread())
:dbObservable
.map(资源::成功)
.OneErrorReturn(t->Resource.error(t.getMessage(),null))
.observeOn(AndroidSchedulers.mainThread())
;
}
可流动的,可流动的{
返回结果;
}
私有列表processResponse(列表响应){
列表=新的ArrayList();
用于(响应数据:响应){
list.add(data.body());
}
退货清单;
}
私有void processInternalError(列表响应)引发java.io.IOException{
用于(响应数据:响应){
if(data.errorBody()!=null){
字符串错误=data.errorBody().String();
抛出异常.propagate(新的Throwable(data.code()+“:”+错误));
}
}
}
抽象void saveCallResult(@NonNull列表项);
抽象的可流动loadFromDb();
抽象流式createCall();
抽象布尔shouldFetch();
}
请注意,.toList()
仅在其上游完成后才会发出
这里的问题很可能是因为此代码返回一个不完整的可流动的
:
containerDao.loadContainerByParentIdRx(s)
如果此Flowable
从未完成,则生成的flatMap
也不会完成,并且toList()
不会发出任何信息
如果只查找数据库一次,那么一个选项是将返回类型更改为Single
或Maybe
。例如,如果切换到可能
,您可以执行以下操作:
@Override
protected Flowable<List<List<DataSource>>> loadFromDb() {
return Flowable.just(parentId).flatMapIterable(d -> d)
.flatMapMaybe(s -> containerDao.loadContainerByParentIdRx(s))
.distinct()
.doOnNext(data -> {
// I am able to get data here
})
.toList() // You should now get this as well.
.toFlowable()
.doOnNext(data -> {
// Nothing here
});
}
@覆盖
受保护的可流动loadFromDb(){
返回可流动的.just(parentId).flatMapIterable(d->d)
.flatmap可能->containerDao.LoadContainerByParentirx
.distinct()
.doOnNext(数据->{
//我可以在这里获得数据
})
.toList()//您现在也应该得到这个。
.toFlowable()
.doOnNext(数据->{
//这里什么都没有
});
}
太棒了,这真的很管用。我完全忘记了flowable()永远不会在房间中完成,因为它会不断更新数据库。
@Override
protected Flowable<List<List<DataSource>>> loadFromDb() {
return Flowable.just(parentId).flatMapIterable(d -> d)
.flatMapMaybe(s -> containerDao.loadContainerByParentIdRx(s))
.distinct()
.doOnNext(data -> {
// I am able to get data here
})
.toList() // You should now get this as well.
.toFlowable()
.doOnNext(data -> {
// Nothing here
});
}