[Android]使用RxJava實現 實時搜索、即時搜索

第一篇技術博客,在這裏試一下。【PS:除了註釋,如下中文內容都是廢話,忽略吧】
以前須要實現一邊輸入一邊實時搜索結果的功能,然而搜索到的資料老是有些不如意,最近有同事須要實現一樣的功能就把我這半年前的筆記用上了,想一想以爲其餘小夥伴應該也有須要,順便我也試一下寫技術博文,就把它放出來給你們參考一下,但願能幫到大家。java

Talk is cheap. Show you the code.ide

Third-party libraries

gson-2.6.2.jar
    okhttp-3.2.0.jar
    okio-1.7.0.jar
    rxAndroid-1.1.0.jar
    rxbinding-0.4.0.jar
    rxjava-1.1.0.jar

Code

public class MainActivity extends AppCompatActivity {
    private EditText et_search;
    private volatile int count = 0;//計數器,用來控制出錯

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_search = (EditText) findViewById(R.id.et_search);

        timeSearch();

    }

    private void timeSearch() {
        Subscription subscribe = RxTextView.textChanges(et_search)//當EditText發生改變
                //每500毫秒發射一次
                //僅在過了一段指定的時間還沒發射數據時才發射一個數據
                //若是原始Observable在這個新生成的Observable終止以前發射了另外一個數據, debounce 會抑制(suppress)這個數據項。
                .debounce(500, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())

                .subscribeOn(AndroidSchedulers.mainThread())//內容監聽操做須要在主線程操做

                //過濾掉EditText沒有內容Observable
                .filter(new Func1<CharSequence, Boolean>() {
                    @Override
                    public Boolean call(CharSequence charSequence) {
                        return charSequence.length() > 0;
                    }
                })

                .observeOn(Schedulers.io())

                //當原始Observable發射一個新的數據( Observable) 時,它將取消訂閱並中止監視產生執以前那個數據的Observable,只監視當前這一個。
                .switchMap(new Func1<CharSequence, Observable<ShopBean>>() {
                    @Override
                    public Observable<ShopBean> call(CharSequence charSequence) {
                        try {
                            count++;
                            System.out.println("count-->" + count);
                            String resultStr = getShops();
                            ShopBean shopBean = new Gson().fromJson(resultStr, ShopBean.class);
                            Observable<ShopBean> just = Observable.just(shopBean);

                            if (count == 3 || count == 7 || count == 10) {    //出錯,將觸發retry
                                System.out.println("錯");
                                return null;
                            } else {
                                return just;
                            }

                        } catch (IOException e) {
                            return null;
                        }
                    }
                })

                .retry()//凡是請求出錯就重試(例如超時、數據解析異常等),直到正確爲止。(若是不retry的話就會調用onError。onError會致使整個訂閱鏈條死掉,沒法觸發下一次了)

//                .retry(3)//最多重試3次,若是次數超了,它不會嘗試從新訂閱,它會把最新的一個onError通知傳遞給它的觀察者。

//                .retry(new Func2<Integer, Throwable, Boolean>() {
//                    @Override
//                    public Boolean call(Integer integer, Throwable throwable) {
//                        System.out.println("捕獲錯誤並retry-->" + throwable.getMessage());
//                        return true;//若是返回true則再次訂閱和鏡像原始的Observable,若是返回false則會將最新的一個onError通知傳遞給它的觀察者。
//                    }
//                })

                //展現結果
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<ShopBean>() {
                    @Override
                    public void onCompleted() {
                    }

                    @Override
                    public void onError(Throwable e) {
                        System.out.println("錯誤-->" + e.getMessage());
                        count = 0;
                        timeSearch();//onError或onCompleted都會終止訂閱,因此須要從新訂閱
                    }

                    @Override
                    public void onNext(ShopBean shopBean) {
                        List<ShopBean.DataBean.ShopsBean> shops = shopBean.getData().getShops();
                        for (int i = 0; i < shops.size(); i++) {
                            System.out.println(shops.get(i).getSshop_n());
                        }
                        System.out.println("-------------");
                    }
                });
    }

    private String getShops() throws IOException {
        String url = "http://192.168.4.25:8088/LGXDJ2/Shops";
        OkHttpClient mOkHttpClient = new OkHttpClient();
        Request.Builder requestBuilder = new Request.Builder().url(url);
        requestBuilder.method("GET", null);
        Request request = requestBuilder.build();
        Call call = mOkHttpClient.newCall(request);
        Response response = call.execute();
        return response.body().string();
    }

}

Thanks

http://www.jianshu.com/p/33c5...
http://blog.csdn.net/johnny90...ui

相關文章
相關標籤/搜索