天天看點

RxJava——響應式程式設計

自從06年開始,Rxandroid公司項目中陸續就開始使用它了,而它的基礎是由Rxjava演變過來的,如今它也是越來越被廣泛使用在商業項目中了,而做為"專業"的自己還是一直對它一知半解,而在實作功能時首先并不會想到用它去架構代碼,而是還是想用着傳統的方式,并不是不想用它,而是對它的使用不太了解有點抗拒,是以接下來準備系統的學下它,以便在未來如果項目中用了Rx相關的東東不至于太陌生,同時也為了自己将來在做項目時能很好的應用它。

在學習一門新技術之前首先得對它有一個大概的認識,也就是理論這方面肯定是少不了的,下面開始!

什麼是Rx?

  • ReactiveX是Reactive Extensions的縮寫,一般簡寫為Rx,由微軟的架構師Erik Meijer上司的團隊開發,在2012年11月開源。
  • Rx是一個程式設計模型,目标是提供一緻的程式設計接口,幫助開發者更友善的處理異步資料,目前Rx支付大部分流行的程式設計語言,比如Java、C#、PHP等。
  • Rx是一函數庫,讓開發者可以利用可觀察序列和LINQ風格查詢操作符來編寫異步和基于事件的程式。
  • 可以這樣定義:Rx = Oberservables + LNIQ + Schedules。
  • ReactiveX不僅僅是程式設計接口,更是一種程式設計思想的突破,Rx還影響了其它的程式庫、架構以及程式設計語言。

Rx模式--觀察者模式

  • 建立:Rx可以友善的建立事件流和資料流。
  • 組合:Rx使用查詢式的操作符組合和變換資料流。
  • 監聽:Rx可以訂閱任何可以觀察的資料流并執行操作。

Rx優點--簡潔

  • 函數式風格:Rx可以友善的建立事件流和資料流。
  • 簡化代碼:Rx操作符可以将複雜的邏輯簡化為很少的幾行代碼。
  • 異步錯誤處理機制:傳統的try/catch沒辦法處理異步計算,Rx提供了合适的錯誤處理機制。
  • 輕松使用開發:Rx的Observables和Schedulers讓開發者可以避免底層線程同步和各種并發問題。

【注】:有些理論可以參考博文:http://blog.csdn.net/u010046908/article/details/50942247

什麼是Rxjava?【主題】

Rxjava是ReactiveX在JVM上的一個實作,也就是說Rxjava是用java語言實作的響應式程式設計,來建立基于事件的異步程式。

提升開發效率,降低維護成本一直是開發團隊永恒不變的宗旨,近一年來國内的技術圈子中越來越多開始提及Rxjava,學習和掌握Rxjava已經很有必要。Rxjava能夠幫助我們簡化代碼邏輯,提升代碼可讀性,這對于提升開發效率,降低後期維護成本很有幫助。

Rxjava正在Android開發中也變得越來越流行【俗稱的RxAndroid,這個在我們公司的項目中就已經大量使用到了】,唯一的問題就是上手不容易,尤其我們都對傳統的指令式程式設計比較熟,但是!!隻要弄明白了,會發現使用Rxjava真的是太棒了,是以有必要好好學習下它。

學習Rxjava

響應式程式設計的主要組成部份是observable、operator和subscriber。一般響應式程式設計的資訊流如下所示:

  Observable -> Operator1 ->  Operator2 -> Operator3 -> Subscriber

其中Observable是事件的生産者,Subscriber是事件最終的消費者,而其資料的轉換由一系列的Operator操作符來執行。

注:因為Subscriber通常是在主線程中執行,是以設計上要求其代碼盡可能簡單,隻對事件做出響應(不對事件或者資料進行修改),而修改事件的工作完全由operator來執行。

有了上面的一大堆理論基礎之後,下面用代碼來直覺的感受一下Rxjava的魅力,編寫一個Hello World!,這裡采用eclipse中的j2se項目來進行學習,因為還木有用到Android相關的東東,脫離開測試比較友善高效。

在正式寫代碼之前,首先得在網上下一個Rxjava的jar包,Rxjava如今最新版是2.x,但是要學習還得先從1.x開始,是以這裡網上下載下傳Rxjava1.3.0,如下:

RxJava——響應式程式設計

下載下傳完之後,建立工程,并将其引入到工程中,接下來就可以開始我們的Hello World啦!!先直覺感受下,不必深糾~

RxJava——響應式程式設計
public class RxHelloWorld {

    public static void main(String[] args) {
        testObservable();
    }

    @SuppressWarnings("deprecation")
    private static void testObservable() {
        // 建立被觀察者Observable
        Observable<String> observable = Observable
                .create(new OnSubscribe<String>() {

                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        subscriber.onNext("Hello World!");
                        subscriber.onCompleted();
                    }
                });
        // 建立觀察者Observer
        Observer<String> observer = new Observer<String>() {

            @Override
            public void onCompleted() {
                System.out.println("observer onCompleted()");
            }

            @Override
            public void onError(Throwable e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onNext(String t) {
                System.out.println("observer onNext():" + t);
            }
        };
        // 被觀察者訂閱(subscribe)觀察者
        observable.subscribe(observer);

    }

}           

編譯運作:

RxJava——響應式程式設計

可以看出消息是由被觀察者Observable發出,由觀察者Observer進行消息處理。那如果說發送"Hello World!"時後面要再加一些字元,可以這樣修改代碼:

RxJava——響應式程式設計

其結果肯定如預期:

RxJava——響應式程式設計

但是!上面的這個做法不符合Rxjava的思想,這是因為它不希望"在産生資料的地方修改資料",是以可以想到第二種方法,如下:

RxJava——響應式程式設計

其結果很顯然也是一樣的被改變,但是!!!這還是不符合Rxjava的程式設計思想,那如果要改變一個資料,應該用它的哪種方式呢?答案揭曉---利用Rxjava的操作符來改變資料流,如何做呢?看下面:

@SuppressWarnings("deprecation")
    private static void testObservable() {
        // 建立被觀察者Observable
        Observable<String> observable = Observable
                .create(new OnSubscribe<String>() {

                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        subscriber.onNext("Hello World!");
                        subscriber.onCompleted();
                    }
                });
        // 建立觀察者Observer
        Observer<String> observer = new Observer<String>() {

            @Override
            public void onCompleted() {
                System.out.println("observer onCompleted()");
            }

            @Override
            public void onError(Throwable e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onNext(String t) {
                System.out.println("observer onNext():" + t);
            }
        };
        // 被觀察者訂閱(subscribe)觀察者
        observable
        .map(new Func1<String, String>() {//利用map操作符對資料進行修改

            @Override
            public String call(String t) {
                return t + "cexo";
            }
        })
        .subscribe(observer);

    }           

其中的Func1這是個什麼東東,好詭異好生澀的樣子,這裡先隻從它的源碼有個初步的認識,之後會具體去了解為啥要這樣寫的:

RxJava——響應式程式設計

一個接口聲明,先不去過多的了解為啥要這麼聲明,光從這個代碼來看就是做一個類型的轉換工作,正好是符合map操作符的意義,了解下既可。

再編譯運作:

RxJava——響應式程式設計

結果一樣,一個這麼簡單的例子要用多種方式來達到相同的功能,主要是為了說明Rxjava的一種思想,可見跟正常的思路還是不太一樣的。

另外這裡提到了一個map操作符的概念,可以上官網去瞅一眼:

RxJava——響應式程式設計

官網看着還挺漂亮的,看下官網提供的有哪些東東:

RxJava——響應式程式設計

可以看到已經有好多語方的版本了,其中第一位就看到了Rxjava啦,接着再看:

RxJava——響應式程式設計

這五大東東實際上就是Rxjava的核心,先有個感觀上的認識,之會會慢慢去學它們的,那我們關心的操作符就列在第二位:

RxJava——響應式程式設計

點開看一下,貌似好多種類,下面大緻看一下:

RxJava——響應式程式設計
RxJava——響應式程式設計
RxJava——響應式程式設計
RxJava——響應式程式設計
RxJava——響應式程式設計
RxJava——響應式程式設計
RxJava——響應式程式設計
RxJava——響應式程式設計
RxJava——響應式程式設計

是不是有點暈了,不用太過着急,之後會一點點去學的,有個大概的認識就成。

在官網首頁上,看到有這麼一個動圖:

RxJava——響應式程式設計

其中說的是debounce操作符,下面可以點選看一下它的具體介紹:

RxJava——響應式程式設計

debounce是過濾操作符中的一種,至于它幹嘛用的這裡先不用操心,未來會學到的,對于上面這麼形象的圖有沒有想像它是一個動态的圖,實際就是動态的:

RxJava——響應式程式設計

可見其官網做得是比較好的,另外可以連結到它的Github的官網上來:

RxJava——響應式程式設計

打開之後就可以看到有各種相關的項目,其中就可以找到我們的Rxjava啦:

RxJava——響應式程式設計

點選進去:

RxJava——響應式程式設計
RxJava——響應式程式設計

那既然Rxjava1.x最終就要淘汰掉了,那還有必要從Rxjava1.x學起麼?很有必要!!!因為2.x就是由1.x演變過來的,核心的東西是沒有變的,而且大部份都是1.x的東東,是以把1.x學好了,就可以很平滑快速的過渡到2.x上來,是以這點要堅信!!