在tutorial之后,我创建了两个用于获取数据的源。我希望如果本地没有数据,我会发送网络请求。但是所有的时间都从本地源获取空对象列表(这是Observable.concat中的第一个)。
对于使用SQLite和SQLBrite包装器的本地源以及用于远程源的Retrofit:
@Override
public Observable<Item> get(String id) {
//creating sql query
return databaseHelper.createQuery(ItemEntry.TABLE_NAME, sqlQuery, id)
.mapToOneOrDefault(mapperFunction, null);
}
存储库中有用于查找可观察对象的方法:
@Override
public Observable<Item> get(String id) {
Observable<Item> local = localDataSource
.get(id)
.doOnNext(new Action1<Item>() {
@Override
public void call(final Item item) {
// put item to cache
}
});
Observable<Item> remote = remoteDataSource
.get(id)
.doOnNext(new Action1<Item>() {
@Override
public void call(final Item item) {
// save item to database and put to cache
}
});
return Observable.concat(local, remote).first();
}
为了获取ID列表,我正在使用下一个方法:
@Override
public Observable<List<Item>> getList(final List<String> ids) {
return Observable
.from(ids)
.flatMap(new Func1<String, Observable<Item>>() {
@Override
public Observable<Item> call(String id) {
return get(id);
}
}).toList();
}
并在片段中订阅:
Subscription subscription = repository
.getList(ids)
.flatMap(new Func1<List<Item>, Observable<Item>>() {
@Override
public Observable<Item> call(List<Item> result) {
return Observable.from(result);
}
})
.toList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<Item>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(List<Item> result) {
// there get list of null objects
}
});
因此,主要目标是首先检查本地存储,如果没有项目 - 向服务器发出请求。但是现在如果item不存在,我得到null而不是发送请求。
有人可以帮我理解原因吗?
答案 0 :(得分:1)
在concat之后调用first()当然会返回第一个项目,无论它是否有效。 Yout first()函数应该验证该值,并且只提交有效的&#39;第一项。
类似的东西:
public void test() {
Integer[] ids = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Observable.from(ids)
.flatMap(new Func1<Integer, Observable<String>>() {
@Override
public Observable<String> call(Integer id) {
return get(id);
}
})
.toList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<String>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(List<String> strings) {
}
});
}
public Observable<String> get(int id) {
return Observable.concat(getLocal(id), getRemote(id))
.first(new Func1<String, Boolean>() {
@Override
public Boolean call(String s) {
return s != null;
}
});
}
public Observable<String> getLocal(int id) {
return Observable.just(id < 5 ? "fromLocal id:"+id : null);
}
public Observable<String> getRemote(int id) {
return Observable.just(id >= 5 ? "fromRemote id:"+id : null);
}
将结果带来:
fromLocal id:1
fromLocal id:2
fromLocal id:3
fromLocal id:4
fromRemote id:5
fromRemote id:6
fromRemote id:7
fromRemote id:8
fromRemote id:9
fromRemote id:10
答案 1 :(得分:1)
你的函数Observable get()返回无穷的Observable因为 mapToOneOrDefault没有自己完成Observable并做出反应 db的更新。您需要限制此Observable的发射,因为 operator concat等待onCompleted事件。
例如,它应该如下所示:
return Observable.concat(localSource.first(), remoteSource)
.filter(new Func1<Item, Boolean>() {
@Override
public Boolean call(Item item) {
return item!= null;
}
});