RxJava入門

RxJava => java響應式編程庫html

入門教程:http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/ 教程很不錯,重點是評論java

基本元素:Observable、Observer編程

基本概念:RxJava基於觀察者模式的思路設計響應式編程,Observable能夠看作是被觀察對象,能夠發出任意事件,經過OnSubscribe接口調用
Observer中的方法,以達到通知觀察者的目的。json

基本實現:網絡

經過Rxjava實現輸出3個字符串:app

定義一個Observable對象:
Observable o1 = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("A");
                subscriber.onNext("A");
                subscriber.onNext("A");
                subscriber.onCompleted();
            }
        });
        
定義一個Observer對象
Observer observer = new Observer() {
            @Override
            public void onCompleted() {ide

            }測試

            @Override
            public void onError(Throwable e) {this

            }.net

            @Override
            public void onNext(Object o) {
                Toast.makeText(SplashActivity.this,o.toString(),Toast.LENGTH_SHORT).show();
            }
        }
將Observable和Observer關聯
o1.subscribe(observer);

完成!

Observable負責接收三個字符串,經過一個監聽該Observable的Observer對象來輸出這3個字符串,與這個例子相似的模型:


class A{

    private String message = "Hello World";
    private InterfaceA interfaceA;
    
    public Interface InterfaceA{
        void call(String message);
    }
    
    public void doMessage(){
        
        if (interfaceA != null) {
            interfaceA.call(messgae);
        } else {
            System.out.println(message);
        }
    }
    
    public void setInterfaceA(InterfaceA interfaceA){
        this.interfaceA = interfaceA;
    }
}

class B {
    InterfaceA ia = new InterfaceA(){
        public void call(String message){
            Log.d("Turman",message);
        }
    }
    A a = new A();
    a.setInterfaceA(ia);
    a.doMessage();

}


幾種建立Observable的封裝:
1.如上面的例子能夠經過just建立一個處理3個字符創的Observable:Observable.just("A","A","A")
2.經過from:Observable.from(new String[]{"A","A","A"})

對Observer的封裝:Subscriber對Observer進行了分裝,增長了onStart方法能夠在onNext被調用前作一些必要的處理,另外,經過
經過Subscriber能夠unsubscribe,避免內存泄露。

變換lift:
    實現輸出一個字符串:
    Observable.just("Hello World")
            .subscribe(new Subscriber() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(String s) {
                Toast.makeText(SplashActivity.this,s,Toast.LENGTH_SHORT).show();
            }
        });
        
    實現輸出字符串的長度:
        Observable.just("Hello World".length())
            .subscribe(new Subscriber() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(int length) {
                Toast.makeText(SplashActivity.this,length+"",Toast.LENGTH_SHORT).show();
            }
        });
    還能夠經過lift實現:
        Observable.just("Hello World").lift(new Observable.Operator<Integer, String>() {
            @Override
            public Subscriber<? super String> call(final Subscriber<? super Integer> subscriber) {
                return new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        subscriber.onCompleted();
                    }

                    @Override
                    public void onError(Throwable e) {
                        subscriber.onError(e);
                    }

                    @Override
                    public void onNext(String s) {
                        int value = s.length();
                        subscriber.onNext(value);
                    }
                };
            }
        }).subscribe(new Subscriber() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(int length) {
                Toast.makeText(SplashActivity.this,length+"",Toast.LENGTH_SHORT).show();
            }
        });
    理解lift很簡單,Observable.Operator接口中經過在新建的Observable<Integer>中調用初始Observable<String>的方法,並將
    Observable<Integer>返回,相似代理。經過lift能夠實現不少自定義的Observable變換,如:
    
    Observable.from(new Integer[]{1,2,3,4,5,6,7,8}).lift(new Observable.Operator<Integer, Integer>() {
            @Override
            public Subscriber<? super Integer> call(final Subscriber<? super Integer> subscriber) {
                return new Subscriber<Integer>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(Integer integer) {
                        if (integer % 2 == 1) {   //只輸出奇數
                            subscriber.onNext(integer);
                        }
                    }
                };
            }
        }).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                Toast.makeText(SplashActivity.this, integer+"",Toast.LENGTH_SHORT).show();
            }
        });
        

lift的幾個封裝:
    Map ->
    
    Observable.just(1,2,3,4).map(new Func1<Integer, Integer>() {
            @Override
            public Integer call(Integer integer) {
                return 1 * 1000;
            }
        }).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer integer) {
                Toast.makeText(SplashActivity.this,integer.toString(),Toast.LENGTH_SHORT).show();
            }
        });
    這是一個簡單的序列變換,將輸出的全部數字乘以100,可是輸入的數據類型沒有變,若是要將輸出的內容進行變換則須要flatMap
    
    flatMap ->
    
    Observable.from(new String[]{"A","B","C"})
                .flatMap(new Func1<String, Observable<Integer>>() {
                    @Override
                    public Observable<Integer> call(String s) {
                        return Observable.just(s.hashCode());
                    }
                }).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer integer) {
                Toast.makeText(SplashActivity.this, integer.toString(),Toast.LENGTH_SHORT).show();
            }
        });
    轉換成輸出3個字符的哈希碼
    
    
    filter ->
        如下例子過濾奇數,輸出偶數:
        Observable.from(new Integer[]{20,21,22,23,24}).filter(new Func1<Integer, Boolean>() {
            @Override
            public Boolean call(Integer integer) {
                return integer % 2 == 0;
            }
        }).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer integer) {
                Toast.makeText(SplashActivity.this, integer.toString(),Toast.LENGTH_SHORT).show();
            }
        });
        
        
關於FuncX和ActionX接口的說明
    FuncX表示的是接口方法有返回值得接口,ActionX表示的是接口方法沒有返回值的接口,
    其中,X-表明接口參數的數量,filter中的例子能夠寫成這樣:
    
        Observable.from(new Integer[]{20,21,22,23,24}).filter(new Func1<Integer, Boolean>() {
            @Override
            public Boolean call(Integer integer) {
                return integer % 2 == 0;
            }
        }).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                Toast.makeText(SplashActivity.this, integer.toString(),Toast.LENGTH_SHORT).show();
            }
        });
    
    
Observer(Subscriber)幾個方法的調用,onNext業務處理,onError在處理異常時調用,onCompleted在處理結束時調用,
因此onNext會調用屢次而onError和onCmpleted值會調用一次。同時,
onError特性:onError() is called if an Exception is thrown at any time. 很贊!

Schedulers:Rxjava中除了lift外另外一個很讚的特性

    能夠指定Observable和Observer的工做線程。
    示例:
        Observable.just("http://www.test.com/users")
                .flatMap(new Func1<String, Observable<String>>() {
                    @Override
                    public Observable<String> call(String s) {
                        return Observable.just("json string");
                    }
                }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        mTextView.setText(s);
                    }
                });
        這個示例模擬了一個網絡請求,在subscribeOn中設置網絡請求在io線程中執行,observeOn中指定更新TextView在UI主線程中執行。
        這裏AndroidSchedulers須要使用RxAndroid庫。
        
其餘幾個經常使用的方法:
    doOnNext:在onNext以前調用,好比須要將服務端返回的數據在顯示到界面前保存等。關於在其中存儲文件阻塞線程的問題,參考:
            http://blog.csdn.net/wangkai0681080/article/details/50772721

        測試示例:
        Observable.just("A").doOnNext(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        try {
                            Thread.sleep(10000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Log.d("Turman",s);
                    }
                }).subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<String>() {
                            @Override
                            public void call(String s) {
                                Toast.makeText(SplashActivity.this,s+"-end",Toast.LENGTH_SHORT).show();
                            }
                });
    

    mergeWith:同類Observable合併     combineLatest:多個Observable組合處理     compose:http://blog.danlew.net/2015/03/02/dont-break-the-chain/             關於:compose(SplashActivity.this.<Integer>bindUntilEvent(ActivityEvent.DESTROY))             參考:http://www.open-open.com/lib/view/open1448189551399.html               參考RxBus:    http://nerds.weddingpartyapp.com/tech/2014/12/24/implementing-an-event-bus-with-rxjava-rxbus/      未完待續 2016/07/12

相關文章
相關標籤/搜索