用户从ui输入一个url,然后我的演示者对其进行验证,如果有效,则将其插入数据库,否则显示错误;我的解决方案如下所示:
@Override
public void addFeed(final String uri) {
Observable.create(new Observable.OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Boolean> subscriber) {
//may contain some database query,if it has,how should i do ?
subscriber.onNext(uri.startsWith(FeedFetcher.FEED_SCHEME) && !uri.startsWith(FeedFetcher.HTTP_SCHEME));
subscriber.onCompleted();
}
}).doOnNext(new Action1<Boolean>() {
@Override
public void call(Boolean aBoolean) {
//insert into db
if (aBoolean)
mFeedModel.add(uri);
}
}).subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean aBoolean) {
if (aBoolean){
mFeedInputView.hideInputError();
}else{
mFeedInputView.showInputError(R.string.url_format_error);
}
}
});
}
**更新**
if (uri.startsWith(FeedFetcher.FEED_SCHEME) || uri.startsWith(FeedFetcher.HTTP_SCHEME)) {
mFeedInputView.hideInputError();
mChannelModel.isChannelExists(uri)
.subscribeOn(Schedulers.computation())
.observeOn(Schedulers.io())
.flatMap(new Func1<Boolean, Observable<RssChannel>>() {
@Override
public Observable<RssChannel> call(Boolean aBoolean) {
if (aBoolean)
return mChannelModel.add(uri);
return Observable.empty();
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<RssChannel>() {
@Override
public void call(RssChannel channel) {
mFeedInputView.addUrlSuccess();
}
});
} else {
mFeedInputView.showInputError(R.string.url_format_error);
}
但我认为将 if(aBoolean) 放在 flapmap 中不是一个漂亮的解决方案。
怎么样:
public void addFeed(String uri) {
Observable.just(uri)
.first(new Func1<String, Boolean>() {
@Override
public Boolean call(String uri) {
return uri.startsWith(FeedFetcher.FEED_SCHEME) && !uri.startsWith(FeedFetcher.HTTP_SCHEME);
}
})
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
mFeedInputView.hideInputError();
}
@Override
public void onError(Throwable e) {
mFeedInputView.showInputError(R.string.url_format_error);
}
@Override
public void onNext(String s) {
mFeedModel.add(uri);
}
});
}
first()
运算符将根据筛选规则筛选出收到的无效 URI,如果未找到有效的 uri(在您的情况下,如果作为参数传递的 uri 无效),则会抛出NoSuchElementException
。
仅当 URI 有效时,才会调用onCompleted()
,以便您可以安全地在那里调用hideInputError()
。 只有在发生错误时才会调用onError()
而不是onCompleted()
,因此在那里进行错误处理是安全的。最后,当 uri 有效时将调用onNext()
,因为first()
运算符忽略无效的 uri,因此可以安全地将其保存在那里。
请注意,我从方法声明中删除了 final
属性。这里不需要它,因为您正在使用 just()
将 uri 本身传递到链中。
另外值得注意的是,您不必为了它而使用RxJava。在您的情况下,如果您不需要异步运行,这可能是一个更干净的解决方案:
public void addFeed(String uri) {
if (uri.startsWith(FeedFetcher.FEED_SCHEME) && !uri.startsWith(FeedFetcher.HTTP_SCHEME)) {
mFeedInputView.hideInputError();
mFeedModel.add(uri);
} else {
mFeedInputView.showInputError(R.string.url_format_error);
}
}
我宁愿以更实用的方式使用这段代码。
Observable.create(new Observable.OnSubscribe<Boolean>())
.map(b -> b = false)
.doOnNext(uri.startsWith(FeedFetcher.FEED_SCHEME) && !uri.startsWith(FeedFetcher.HTTP_SCHEME))
.map(b -> {
mFeedModel.add(uri);
b=true;
return b;
})
.subscribe(b-> {
if(!b){
mFeedInputView.showInputError(R.string.url_format_error);
}
});