RxJava

RxJava是ReactiveX的一種Java實(shí)現(xiàn)。ReactiveX是Reactive Extensions的縮寫,一般簡寫為Rx。開發(fā)者可以用Observables表示異步數(shù)據(jù)流,用LINQ操作符查詢異步數(shù)據(jù)流,用Schedulers參數(shù)化異步數(shù)據(jù)流的并發(fā)處理,Rx可以這樣定義:Rx = Observables + LINQ + Schedulers。

  • 或許你會問:我為什么要選擇RxJava ?
一般我們在開發(fā)的時候,只要說到異步操作,就會想到Android的AsyncTask和Handler。但是隨著請求的數(shù)量越來越多,
代碼邏輯將會變得越來越復(fù)雜,而RxJava卻仍舊能保持清晰的邏輯。RxJava的原理就是創(chuàng)建一個Observable對象來干活,
然后使用各種操作符建立起來的鏈?zhǔn)讲僮鳎腿缤魉€一樣,把你想要處理的數(shù)據(jù)一步一步加工成你想要的成品,
然后發(fā)射給Subscriber處理。
  • RxJava與觀察者模式
RxJava的異步操作是通過擴(kuò)展的觀察者模式來實(shí)現(xiàn)的。RxJava有4個角色:Observable、Observer、Subscriber和Suject。
Observable和Observer通過subscribe方法實(shí)現(xiàn)訂閱關(guān)系,Observable就可以在需要的時候通知Observer。
  • RxJava的實(shí)現(xiàn)

在使用RxJava前請先在AndroidStudio配置gradle:(此處以RxJava為例,不使用RxJava2)

dependencies {
    ...

    compile 'io.reactivex:rxjava:1.2.0'
    compile 'io.reactivex:rxandroid:1.2.1'
}

看到這里可能會問:我使用的是RxJava,為什么還要引入RxAndroid ?

RxAndroid是RxJava在Android平臺的擴(kuò)展。包含了一些能夠簡化Android開發(fā)的工具,比如特殊的調(diào)度器。

  • RxJava的使用

RxJava的使用可以分為3個步驟:創(chuàng)建Observable(被觀察者)、創(chuàng)建Observer(觀察者)、Subscribe(訂閱)。

創(chuàng)建Observable(被觀察者)

Observable它決定什么時候觸發(fā)事件以及觸發(fā)怎樣的事件。RxJava使用 create 方法來創(chuàng)建一個Observable,并未它定義時間觸發(fā)規(guī)則。例如:

        // 創(chuàng)建Observable(被觀察者)
        Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("張三");
                subscriber.onNext("李四");
                subscriber.onCompleted();
            }
        });

通過調(diào)用Subscriber的方法,不斷的將事件添加到任務(wù)隊列中。

創(chuàng)建Observer(觀察者)

Observer 它決定事件觸發(fā)的時候?qū)⒂性趺礃拥男袨椤?/p>

        // 創(chuàng)建Observer(觀察者)
        Subscriber<String> subscriber = new Subscriber<String>() {
            @Override
            public void onStart() {
                Log.e(TAG, "onStart");
            }

            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError");
            }

            @Override
            public void onNext(String s) {
                Log.e(TAG, "onNext" + s);
            }
        };

其中,onCompleted、onError和onNext是必須要實(shí)現(xiàn)的方法。其具體含義如下:

  • onCompleted:事件隊列完結(jié)。RxJava不僅把每個事件單獨(dú)處理,其還會把它們看作一個隊列。當(dāng)不會有新的 onNext 發(fā)出時,需要觸發(fā) onComplete() 方法作為完成標(biāo)志。

  • onError:事件隊列異常。在事件處理過程中出現(xiàn)異常時,onError() 方法會被觸發(fā),同時隊列自動終止,不允許再有事件發(fā)出。

  • onNext():普通的事件。將要處理的事件添加到事件隊列中。

  • onStart():它會在事件還未發(fā)送之前被調(diào)用,可以用于做一些準(zhǔn)備工作。例如數(shù)據(jù)的清零或重置。這是一個可選方法,默認(rèn)情況下它的實(shí)現(xiàn)為空。

當(dāng)然,如果要實(shí)現(xiàn)簡單的功能,也可以用到Observer來創(chuàng)建觀察者。Observer是一個接口,而上面用到的Subscriber是在Observer的基礎(chǔ)上進(jìn)行的擴(kuò)展。在后文的Subscribe訂閱過程中Observer也會被轉(zhuǎn)換為Subscriber來使用。如果用Observer創(chuàng)建觀察者對象,如下:

Observer<String> observer = new Observer<String>() {
            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError");
            }

            @Override
            public void onNext(String s) {
                Log.e(TAG, "onNext" + s);
            }
        };

Subscribe(訂閱)

observable.subscribe(subscriber);

運(yùn)行代碼可查看Log:

E/RxJavaActivity: onStart
E/RxJavaActivity: onNext張三
E/RxJavaActivity: onNext李四
E/RxJavaActivity: onCompleted

RxJava操作符

RxJava操作符類型可以分為:創(chuàng)建操作符、變換操作符、過濾操作符、組合操作符、錯誤處理操作符、輔助操作符、條件和布爾操作符、算術(shù)和聚合操作符及連續(xù)操作符等,而這些操作符類型下又有很多操作符,每個操作符可能還有很多變體。此處,簡單的介紹一些創(chuàng)建操作符、變換操作符、過濾操作符、輔助操作符、錯誤處理操作符。

創(chuàng)建操作符

  • Interval

創(chuàng)建一個按固定時間間隔發(fā)射整數(shù)序列的Observable,相當(dāng)于定時器,如下:

Observable.interval(3, TimeUnit.SECONDS)
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        Log.e(TAG, "interval:" + aLong.intValue());
                    }
                });

上面的代碼每個3s就會調(diào)用call方法并打印Log。

  • Range

創(chuàng)建發(fā)射指定范圍的整數(shù)序列的Observable,可以拿來代替for循環(huán),發(fā)射一個范圍內(nèi)的有序整數(shù)序列。第一個參數(shù)是起始值,并不小于0;第二個參數(shù)為整數(shù)序列的個數(shù)。

Observable.range(0, 5)
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        Log.e(TAG, "range:" + integer.intValue());
                    }
                });

運(yùn)行代碼可查看Log:

E/RxJavaActivity: range:0
E/RxJavaActivity: range:1
E/RxJavaActivity: range:2
E/RxJavaActivity: range:3
E/RxJavaActivity: range:4
  • Repeat

創(chuàng)建一個N次重復(fù)發(fā)射特定數(shù)據(jù)的Observable,如下:

Observable.range(0, 3)
                .repeat(2)
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        Log.e(TAG, "repeat:" + integer.intValue());
                    }
                });

運(yùn)行代碼可查看Log:

E/RxJavaActivity: repeat:0
E/RxJavaActivity: repeat:1
E/RxJavaActivity: repeat:2
E/RxJavaActivity: repeat:0
E/RxJavaActivity: repeat:1
E/RxJavaActivity: repeat:2

變換操作符

  • Map

map操作符通過指定一個Func對象,將Observable轉(zhuǎn)換為一個新的Observable對象并發(fā)射,觀察者將收到最新的Observable處理。例如:

final String host = "https://github.com/";
        Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {

                subscriber.onNext("JiaYang627");
            }
        }).map(new Func1<String, String>() {
            @Override
            public String call(String s) {
                return host + s;
            }
        }).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                Log.e(TAG, "map:" + s);
            }
        });

運(yùn)行代碼查看Log:

E/RxJavaActivity: map:https://github.com/JiaYang627

過濾操作符

  • Filter

Filter操作符是對源Observable產(chǎn)生的結(jié)果自定義規(guī)則進(jìn)行過濾,只有滿足條件的結(jié)果才會交給訂閱者。例如:

 Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                subscriber.onNext(1);
                subscriber.onNext(2);
                subscriber.onNext(3);
                subscriber.onNext(4);

            }
        }).filter(new Func1<Integer, Boolean>() {
            @Override
            public Boolean call(Integer integer) {
                return integer > 2;
            }
        }).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                Log.e(TAG, "filter:" + integer);
            }
        });

運(yùn)行代碼查看Log:

E/RxJavaActivity: filter:3
E/RxJavaActivity: filter:4

輔助操作符

  • Do

Do系列操作符是為原始Observable的生命周期事件注冊一個回調(diào),當(dāng)Observable的某個事件發(fā)生時就會調(diào)用這些回調(diào)。RxJava中有很多Do系列操作符,如下:

  • doOnEach:為Observable注冊這樣一個回調(diào):當(dāng)Observable每當(dāng)發(fā)射一項數(shù)據(jù)時就會調(diào)用它一次,包括onNext、onError和onCompleted。
  • doOnNext:只有執(zhí)行onNext的時候會被調(diào)用。
  • doOnSubscribe:當(dāng)觀察者訂閱Observable時就會被調(diào)用。
  • doOnUnsubscribe:當(dāng)觀察者取消訂閱Observable時就會被調(diào)用;Observable通過onError或者onCompleted結(jié)束時,會取消訂閱所有的Subscriber。
  • doOnCompleted:當(dāng)Observable正常終止調(diào)用onCompleted時會被調(diào)用。
  • doOnError:當(dāng)Observable異常終止調(diào)用onError時會被調(diào)用。
  • doOnTerminate:當(dāng)Observable終止(無論是正常終止還是異常終止)之前會被調(diào)用。
  • finallyDo:當(dāng)Observable終止(無論是正常終止還是異常終止)之后會被調(diào)用。

此處以doOnNext為例,如下:

 Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                subscriber.onNext(1);
                subscriber.onNext(2);
            }
        }).doOnNext(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                Log.e(TAG, "doOnNext:" + integer);
            }
        }).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer integer) {
                Log.e(TAG, "subscribe_onNext:" + integer);
            }
        });

運(yùn)行代碼查看Log:

E/RxJavaActivity: doOnNext:1
E/RxJavaActivity: subscribe_onNext:1
E/RxJavaActivity: doOnNext:2
E/RxJavaActivity: subscribe_onNext:2
  • SubscribeOn、ObserverOn

SubscribeOn操作符用于指定Obserable自身在哪個線程上運(yùn)行。如果Observable需要執(zhí)行耗時操作,一般可以讓其在新開的一個子線程上運(yùn)行。ObserverOn用來指定Observer所運(yùn)行的線程,也就是發(fā)射出的數(shù)據(jù)在哪個線程上使用。一般情況下會指定砸死主線程中運(yùn)行,這樣就可以修改UI。如下:

 Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                Log.e(TAG, "Observable:" + Thread.currentThread().getName());
                subscriber.onNext(1);
            }
        }).subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe(new Action1<Integer>() {
              @Override
              public void call(Integer integer) {
                  Log.e(TAG, "Observer:" + Thread.currentThread().getName());
              }
          });

運(yùn)行代碼查看Log:

E/RxJavaActivity: Observable:RxIoScheduler-2
E/RxJavaActivity: Observer:main

其中,AndroidSchedulers是RxAndroid庫中提供的Scheduler。

錯誤處理操作符

  • Retry

Retry操作符不會將原始Observable的onError通知傳遞給觀察者,它會訂閱這個Observable再給它一次機(jī)會無錯誤地完成其數(shù)據(jù)序列。Retry總是傳遞onNext通知給觀察者,由于重新訂閱,這可能會造成數(shù)據(jù)項重復(fù)。RxJava中的實(shí)現(xiàn)為Retry和RetryWhen。此處以Retry為例說明。

它指定最多重新訂閱的次數(shù),如果次數(shù)超了,它不會嘗試再次訂閱,而會把最新的一個onError通知傳遞給自己的觀察者。如下:

Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                for (int i =0 ; i < 5 ; i ++) {
                    if (i == 1) {
                        subscriber.onError(new Throwable("Throwable"));
                    } else {
                        subscriber.onNext(i);
                    }
                }
            }
        }).retry(2)
          .subscribe(new Subscriber<Integer>() {
              @Override
              public void onCompleted() {
                  Log.e(TAG, "onCompleted");
              }

              @Override
              public void onError(Throwable e) {
                  Log.e(TAG, "onError:" + e.getMessage());
              }

              @Override
              public void onNext(Integer integer) {
                  Log.e(TAG, "onNext:" + integer);
              }
          });

如上所示,Observable中走了一個for循環(huán),當(dāng)i為0時走onNext,當(dāng)i為1時讓走onError,然后,此時會重新訂閱,再次走for循環(huán),此為第一次重新訂閱。在第二次重新訂閱的時候,走到onError后不會再次重新訂閱,運(yùn)行代碼查看Log:

E/RxJavaActivity: onNext:0
E/RxJavaActivity: onNext:0
E/RxJavaActivity: onNext:0
E/RxJavaActivity: onError:Throwable

RxJava結(jié)合Retrofit訪問網(wǎng)絡(luò)

此處使用自己寫的MVP框架Demo為例,使用的是RxJava2、Retrofit2。

  • 首先配置build.gradle:
dependencies {
    ...
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
    compile 'io.reactivex.rxjava2:rxjava:2.1.0'
    
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    compile 'org.ligboy.retrofit2:converter-fastjson-android:2.1.0'
    compile 'com.squareup.retrofit2:converter-scalars:2.1.0'
    
    compile 'com.alibaba:fastjson:1.2.33'

}

以上為配置依賴,Demo中使用FastJson數(shù)據(jù)解析。

配置Retorfit:

private Retrofit creatRetrofit(Retrofit.Builder builder, String baseUrl, OkHttpClient client){
        builder.client(client)
                .baseUrl(baseUrl)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(FastJsonConverterFactory.create());
        return builder.build();
    }
  • 注意:由于MVP框架使用的是Dagger2 + RxJava2 + Retrofit2 + OkHttp3 + FastJson。此處只說配置Retrofit。

上面配置Retrofit的時候,添加 addCallAdapterFactory方法,這樣此前Retrofit定義的接口返回的就不是Call了,而是Observalbe,這樣就能用RxJava提供的方法來對請求網(wǎng)絡(luò)的回調(diào)進(jìn)行處理。添加的addConverterFactory方法支持對返回結(jié)構(gòu)的支持類型,此處支持的為FastJson 和String類型。

最后,給出MVP框架的地址,此項目框架采用 OkHttp3 + RxJava2 + Retrofit2 + Dagger2 + FastJson 為主體的 mvp框架。里面有詳細(xì)的Retrofit配置,已經(jīng)RxJava請求聯(lián)網(wǎng)時線程轉(zhuǎn)換。

Demo:
MVPFramework

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容