Android 基于结果的观测值链接

Android 基于结果的观测值链接,android,reactive-programming,rx-java,rx-android,Android,Reactive Programming,Rx Java,Rx Android,我是rx java和rx android的完全初学者。我听说一开始学习曲线相当陡峭 我试图通过使用rx android将所有基于Eventbus的代码替换为更安全的代码 我将此代码段设置为从编辑文本更改事件创建可观察项: main活动 RxUtils.createEditTextChangeObservable(txtInput).throttleLast(200, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread()).subscribe(

我是rx java和rx android的完全初学者。我听说一开始学习曲线相当陡峭

我试图通过使用rx android将所有基于Eventbus的代码替换为更安全的代码

我将此代码段设置为从编辑文本更改事件创建可观察项:

main活动

RxUtils.createEditTextChangeObservable(txtInput).throttleLast(200, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread()).subscribe(new Action1<EditText>() {
            @Override
            public void call(EditText editText) {
                searchStopResultFragment.query(editText.getText().toString());
            }
        });
RxUtils.createEditTextChangeObservable(txtInput).throttleLast(200,TimeUnit.mills,AndroidSchedulers.mainThread()).subscribe(新操作1()){
@凌驾
公共作废调用(EditText EditText){
searchStopResultFragment.query(editText.getText().toString());
}
});
RxUtils:

public static Observable<EditText> createEditTextChangeObservable(final EditText editText){
        return Observable.create(new Observable.OnSubscribe<EditText>() {
            @Override
            public void call(final Subscriber<? super EditText> subscriber) {
                editText.addTextChangedListener(new TextWatcher() {
                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                    }

                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {

                    }

                    @Override
                    public void afterTextChanged(Editable s) {
                        if (subscriber.isUnsubscribed()) return;
                        subscriber.onNext(editText);
                    }
                });
            }
        });
    }
public void query(String query){
        lastQuery = query;
        resultObservable = StopProvider.getStopResultObservable(getActivity().getContentResolver(),query);
        subscription = resultObservable.subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<List<Stop>>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(List<Stop> stops) {
                if(!lastQuery.equals("")) {

                    if(stops.size()>0) {

                        ArrayList<AdapterItem> items = adapter.getItems();
                        items.clear();

                        for (Stop stop : stops) {
                            SearchResultStopItem item = new SearchResultStopItem(stop, SearchResultStopItem.STOP);
                            items.add(item);

                        }

                        adapter.setItems(items);
                        adapter.notifyDataSetChanged();
                    }else{
                      //DO A NOTHER ASYNC QUERY TO FETCH RESULTS
                    }
                }else{
                    showStartItems();
                }
            }
        });
    }
公共静态可观察createEditTextChangeObservable(最终EditText EditText){
返回Observable.create(newobservable.OnSubscribe(){
@凌驾

公共无效呼叫(最终用户使用concatmap和最新组合解决:

 RxUtils.createEditTextChangeObservable(txtInput).throttleLast(200, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread()).concatMap(new Func1<EditText, Observable<Pair<String,List<Stop>>>>() {
            @Override
            public Observable<Pair<String, List<Stop>>> call(EditText editText) {
                String query = editText.getText().toString();
                //searchStopResultFragment.setLastQuery(query);
                if(query.isEmpty()){
                    return Observable.just(null);
                }
                return Observable.combineLatest(StopProvider.getStopResultObservable(getContentResolver(), query), Observable.just(query), new Func2<List<Stop>, String, Pair<String, List<Stop>>>() {
                    @Override
                    public Pair<String, List<Stop>> call(List<Stop> stops, String s) {
                        return new Pair(s,stops);
                    }
                });
            }
        }).concatMap(new Func1<Pair<String, List<Stop>>, Observable<List<Stop>>>() {
            @Override
            public Observable<List<Stop>> call(Pair<String, List<Stop>> queryAndStops) {
                if(queryAndStops!=null) {
                    if (queryAndStops.second.size() == 0) {
                        return RestClient.service().locationName(queryAndStops.first).concatMap(new Func1<LocationNameResponse, Observable<? extends List<Stop>>>() {
                            @Override
                            public Observable<? extends List<Stop>> call(LocationNameResponse locationNameResponse) {
                                return Observable.just(locationNameResponse.getAddresses());
                            }
                        });
                    } else {
                        return Observable.just(queryAndStops.second);
                    }
                }
                return Observable.just(null);

            }
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread()).compose(this.<List<Stop>>bindToLifecycle()).subscribe(new Action1<List<Stop>>() {
            @Override
            public void call(List<Stop> stops) {
                if (stops != null) {
                    searchStopResultFragment.showStops(stops);
                }else{
                    searchStopResultFragment.showStartItems();
                }

            }
        }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                showError(throwable);
            }
        });
RxUtils.createEditTextChangeObservable(txtInput).throttleLast(200,TimeUnit.ms,AndroidSchedulers.mainThread()).concatMap(新函数1(){
@凌驾
公共可观察调用(EditText EditText){
字符串查询=editText.getText().toString();
//searchStopResultFragment.setLastQuery(查询);
if(query.isEmpty()){
返回可观察值。just(null);
}
返回Observable.CombineTest(StopProvider.GetStopResultToServable(getContentResolver(),query),Observable.just(query),new Func2(){
@凌驾
公共对呼叫(列表停止,字符串s){
返回新的一对(s,停止);
}
});
}
}).concatMap(新函数1(){
@凌驾
公共可观测呼叫(成对查询操作){
if(queryAndStops!=null){
if(queryAndStops.second.size()==0){

返回RestClient.service().locationName(queryAndStops.first).concatMap(new Func1在组合测试之后,您可以将第二个concatMap移动到您需要它的唯一位置

    RxUtils.createEditTextChangeObservable(txtInput)
            .throttleLast(200, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
            .concatMap(new Func1<EditText, Observable<Pair<String, List<Stop>>>>() {
                @Override
                public Observable<Pair<String, List<Stop>>> call(EditText editText) {
                    String query = editText.getText().toString();
                    //searchStopResultFragment.setLastQuery(query);
                    if (query.isEmpty()) {
                        return Observable.just(null);
                    }
                    return Observable
                            .combineLatest(StopProvider.getStopResultObservable(getContentResolver(), query), Observable.just(query), new Func2<List<Stop>, String, Pair<String, List<Stop>>>() {
                                @Override
                                public Pair<String, List<Stop>> call(List<Stop> stops, String s) {
                                    return new Pair(s, stops);
                                }
                            })
                            .concatMap(new Func1<R, Observable<? extends Pair<String, List<Stop>>>>() {
                                @Override
                                public Observable<? extends Pair<String, List<Stop>>> call(R r) {
                                    if (queryAndStops.second.size() == 0) {
                                        return RestClient.service().locationName(queryAndStops.first).concatMap(new Func1<LocationNameResponse, Observable<? extends List<Stop>>>() {
                                            @Override
                                            public Observable<? extends List<Stop>> call(LocationNameResponse locationNameResponse) {
                                                return Observable.just(locationNameResponse.getAddresses());
                                            }
                                        });
                                    } else {
                                        return Observable.just(queryAndStops.second);
                                    }
                                }
                            });
                }
            })
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread()).compose(this.<List<Stop>>bindToLifecycle())
            .subscribe(new Action1<List<Stop>>() {
                @Override
                public void call(List<Stop> stops) {
                    if (stops != null) {
                        searchStopResultFragment.showStops(stops);
                    } else {
                        searchStopResultFragment.showStartItems();
                    }

                }
            }, new Action1<Throwable>() {
                @Override
                public void call(Throwable throwable) {
                    showError(throwable);
                }
            });
RxUtils.createEditTextChangeObservable(txtInput)
.throttleLast(200,TimeUnit.ms,AndroidSchedulers.mainThread())
.concatMap(新函数1(){
@凌驾
公共可观察调用(EditText EditText){
字符串查询=editText.getText().toString();
//searchStopResultFragment.setLastQuery(查询);
if(query.isEmpty()){
返回可观察值。just(null);
}
可观测回波
.CombineTest(StopProvider.GetStopResultoServable(getContentResolver(),查询),Observable.just(查询),new Func2(){
@凌驾
公共对呼叫(列表停止,字符串s){
返回新的一对(s,停止);
}
})

.concatMap(新函数1以下是我的想法:

RxUtils.createEditTextChangeObservable(txtInput)
.throttleLast(200, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
.map(EXTRACT_STRING)
.filter(STRING_IS_NOT_EMPTY)
.concatMap(new Func1<EditText, Observable<Pair<String,List<Stop>>>>() {

    @Override
    public Observable<Pair<String, List<Stop>>> call(final String query) {

        return StopProvider.getStopResultObservable(getContentResolver(), query)
        .map(new Func1<List<Stop>, Pair<String, List<Stop>>>() {
            // I think this map is a bit more readable than the 
            // combineLatest, and since "query" should not be changing 
            // anyway, the result should be the same (you have to 
            // declare it as final in the method signature, though
            @Override
            public Pair<String, List<Stop>> call(List<Stop> stops) {
                return new Pair(query, stops);
            }
        });
    }
)
.concatMap(new Func1<Pair<String, List<Stop>>, Observable<List<Stop>>>() {

    @Override
    public Observable<List<Stop>> call(Pair<String, List<Stop>> queryAndStops) {
        if (queryAndStops.second.size() == 0) {
            return RestClient.service().locationName(queryAndStops.first)
                       .map(new Func1<LocationNameResponse, List<Stop>>() {

                            @Override
                            public List<Stop> call(LocationNameResponse locationNameResponse) {
                                // since there was no if-else in your original code (you were always
                                // just wrapping the List in an Observable) I removed that, too
                                return locationNameResponse.getAddresses();
                            }
            });
        } else {
            return Observable.just(queryAndStops.second);
        }
    }
)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.compose(this.<List<Stop>>bindToLifecycle())
.subscribe(new Action1<List<Stop>>() {
    @Override
    public void call(List<Stop> stops) {
        // since I don't know what your API is returning I think
        // it's saver to keep this check in:
        if (stops != null) {
            searchStopResultFragment.showStops(stops);
        } else {
            searchStopResultFragment.showStartItems();
        }
    }
},
new Action1<Throwable>() {
    @Override
    public void call(Throwable throwable) {
        showError(throwable);
    }
});
RxUtils.createEditTextChangeObservable(txtInput)
.throttleLast(200,TimeUnit.ms,AndroidSchedulers.mainThread())
.map(提取字符串)
.filter(字符串\u不是空的)
.concatMap(新函数1(){
@凌驾
公共可观察调用(最终字符串查询){
返回StopProvider.GetStopResultoServable(getContentResolver(),查询)
.map(新函数1(){
//我认为这张地图比地图可读性好一点
//CombineTest,因为“查询”不应更改
//无论如何,结果应该是一样的(你必须
//不过,在方法签名中将其声明为final
@凌驾
公共对呼叫(列出站点){
返回新对(查询、停止);
}
});
}
)
.concatMap(新函数1(){
@凌驾
公共可观测呼叫(成对查询操作){
if(queryAndStops.second.size()==0){
返回RestClient.service().locationName(queryAndStops.first)
.map(新函数1(){
@凌驾
公共列表调用(LocationNameResponse LocationNameResponse){
//因为在您的原始代码中没有if-else(您总是
//只是将列表包装成一个可观察的)我也删除了它
返回locationNameResponse.getAddresses();
}
});
}否则{
返回可观察的。just(queryAndStops.second);
}
}
)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.compose(this.bindToLifecycle())
.订阅(新操作1(){
@凌驾
公共无效呼叫(列出站点){
//因为我不知道你的API返回了什么,我想
//保持此签入状态非常重要:
如果(停止!=null){
searchStopResultFragment.showStops(停止);
}否则{
searchStopResultFragment.showStartItems();
}
}
},
新行动1(){
@凌驾
公共无效呼叫(可丢弃可丢弃){
淋浴器(可丢弃);
}
});
其中:

public static final Func1<EditText, String> EXTRACT_STRING = new Func1<EditText, String>() {

    @Override
    public void String call(EditText editText) {
        return editText.getText().toString();
    }
};

public static final Func1<String, Boolean> STRING_IS_NOT_EMPTY = new Func1<String, Boolean>() {

    @Override
    public void String call(String string) {
        return !string.isEmpty();
    }
};
public static final Func1 EXTRACT\u STRING=new Func1(){
@凌驾
公共无效字符串调用(EditText EditText){
返回editText.getText().toString();
}
};
公共静态最终Func1字符串\u为\u非\u空=新Func1(){
@凌驾
公共无效字符串调用(字符串){
return!string.isEmpty();
}
};
因此,这至少消除了返回
Observable.just(null)
的需要,然后在链的下面检查它。

使您的query()方法返回