RxJava入門與提高(1)

前言

本教程是我自己學習Rxjava的系列總結。幫你從淺入深的學習RxJava。該系列借鑒了很多網上的優(yōu)秀文章,并根據我的理解和學習經驗,加以總結和抽取,方便大家理解。

據說RxJava的入門門檻高,而經過我這幾天的學習,我反而不那么認為,精通我不敢說,但入門確實也不難,不信?我先來個簡單的例子預熱一下。

先創(chuàng)建個數據發(fā)射源,很好理解,就是發(fā)射數據用的:

Observablesender = Observable.create(new Observable.OnSubscribe() {
      @Override
      public void call(Subscribersubscriber) {
        subscriber.onNext("Hi,Weavey!");  //發(fā)送數據"Hi,Weavey!"
      }
});

再創(chuàng)建個數據接收源,同理,接收數據用的:

Observer receiver = new Observer() {

      @Override
      public void onCompleted() {
      //數據接收完成時調用
      }

      @Override  
      public void onError(Throwable e) {
      //發(fā)生錯誤調用
      }

      @Override
      public void onNext(String s) {
      //正常接收數據調用
            System.out.print(s);  //將接收到來自sender的問候"Hi,Weavey!"
      }
};

好了,將發(fā)射源和接收源關聯起來:

sender.subscribe(receiver);

這樣就形成RxJava一個簡單的用法,sender發(fā)射"Hi,Weavey!",將會被receiver的onNext的接收,通過這個例子,也許你會想到“異步”、“觀察者模式”,沒錯,這些都是RxJava所做的事情,并且讓他們變得更簡單和簡潔,而RxJava所有的一切都將圍繞這兩個點展開,一個是發(fā)射數據,一個是接收數據,是不是很通俗易懂?如果你理解了這點或者你已經知道RxJava就是這么一回事,那么恭喜你,你已經一只腳跨進RxJava的大門了,如果不是?。。?!那也無所謂,請繼續(xù)往下看...

基本概念

論概念的重要性
在講RxJava中各種強大的操作符之前,先說說最基本的東西——概念。舉個不太恰當的例子,概念之于初學者,就像食物之于人,當你餓了,你會想吃面包、牛奶,那你為什么不去吃土呢,因為你知道面包牛奶是用來干嘛的,土是用來干嘛的。同理,前面已經說過,RxJava無非是發(fā)送數據與接收數據,那么什么是發(fā)射源,什么是接收源,這就是你應該明確的事,也是RxJava的入門條件之一,下面就依我個人理解,對發(fā)射源和接收源做個歸類,以及RxJava中頻繁出現的幾個“單詞”解釋一通,說的不好還請海涵,歡迎補充。

Observable:發(fā)射源,英文釋義“可觀察的”,在觀察者模式中稱為“被觀察者”或“可觀察對象”;

Observer:接收源,英文釋義“觀察者”,沒錯!就是觀察者模式中的“觀察者”,可接收Observable、Subject發(fā)射的數據;

Subject:Subject是一個比較特殊的對象,既可充當發(fā)射源,也可充當接收源,為避免初學者被混淆,本章將不對Subject做過多的解釋和使用,重點放在Observable和Observer上,先把最基本方法的使用學會,后面再學其他的都不是什么問題;

Subscriber:“訂閱者”,也是接收源,那它跟Observer有什么區(qū)別呢?Subscriber實現了Observer接口,比Observer多了一個最重要的方法unsubscribe( ),用來取消訂閱,當你不再想接收數據了,可以調用unsubscribe( )方法停止接收,Observer 在subscribe()過程中,最終也會被轉換成 Subscriber 對象,一般情況下,建議使用Subscriber作為接收源;

Subscription:Observable調用subscribe( )方法返回的對象,同樣有unsubscribe( )方法,可以用來取消訂閱事件;

Action0:RxJava中的一個接口,它只有一個無參call()方法,且無返回值,同樣還有Action1,Action2...Action9等,Action1封裝了含有1個參的call()方法,即call(T t),Action2封裝了含有2個參數的call方法,即call(T1 t1,T2 t2),以此類推;

Func0:與Action0非常相似,也有call()方法,但是它是有返回值的,同樣也有Func0、Func1...Func9;

基本用法

Observable的創(chuàng)建

1.使用create( ),最基本的創(chuàng)建方式:

normalObservable = Observable.create(new Observable.OnSubscribe() {
      @Override
      public void call(Subscriber subscriber) {
            subscriber.onNext("create1"); //發(fā)射一個"create1"的String
            subscriber.onNext("create2"); //發(fā)射一個"create2"的String
            subscriber.onCompleted();//發(fā)射完成,這種方法需要手動調用onCompleted,才會回調Observer的onCompleted方法
      }});

2.使用just( ),將為你創(chuàng)建一個Observable并自動為你調用onNext( )發(fā)射數據:

justObservable = Observable.just("just1","just2");//依次發(fā)送"just1"和"just2"

3.使用from( ),遍歷集合,發(fā)送每個item:

List list = new ArrayList<>();

list.add("from1");

list.add("from2");

list.add("from3");

fromObservable = Observable.from(list);  //遍歷list 每次發(fā)送一個

注意 just()方法也可以傳list,但是發(fā)送的是整個list對象,而from()發(fā)送的是list的一個item

4.使用defer( ),有觀察者訂閱時才創(chuàng)建Observable,并且為每個觀察者創(chuàng)建一個新的Observable:

deferObservable = Observable.defer(new Func0>() {
      @Override
      //注意此處的call方法沒有Subscriber參數
      public Observable call() {
      return Observable.just("deferObservable");
}});

5.使用interval( ),創(chuàng)建一個按固定時間間隔發(fā)射整數序列的Observable,可用作定時器:

intervalObservable = Observable.interval(1, TimeUnit.SECONDS);//每隔一秒發(fā)送一次

6.使用range( ),創(chuàng)建一個發(fā)射特定整數序列的Observable,第一個參數為起始值,第二個為發(fā)送的個數,如果為0則不發(fā)送,負數則拋異常:

rangeObservable = Observable.range(10, 5);//將發(fā)送整數10,11,12,13,14

7.使用timer( ),創(chuàng)建一個Observable,它在一個給定的延遲后發(fā)射一個特殊的值,等同于Android中Handler的postDelay( )方法:

timeObservable = Observable.timer(3, TimeUnit.SECONDS);  //3秒后發(fā)射一個值

8.使用repeat( ),創(chuàng)建一個重復發(fā)射特定數據的Observable:

repeatObservable = Observable.just("repeatObservable").repeat(3);//重復發(fā)射3次

另外,還有

  • Observable.empty() 創(chuàng)建一個空的,不會發(fā)射任何事件(數據)的Observable
  • Observable.never() 創(chuàng)建一個不會發(fā)出任何事件也不會結束的Observable
  • Observable.error(new RuntimeException("fuck!")) 創(chuàng)建一個會發(fā)出一個error事件的Observable
    等等

Observer的創(chuàng)建

mObserver = new Observer() {

    @Override
    public void onCompleted() {
        LogUtil.log("onCompleted");
    }

    @Override
     public void onError(Throwable e) {

    }

    @Override
    public void onNext(String s) {
        LogUtil.log(s);
  }};

ok,有了Observable和Obsever,我們就可以隨便玩了,任取一個已創(chuàng)建的Observable和Observer關聯上,即形成一個RxJava的例子,如:

justObservable.subscribe(mObserver);

mObserver的onNext方法將會依次收到來自justObservable的數據"just1"、"just2",另外,如果你不在意數據是否接收完或者是否出現錯誤,即不需要Observer的onCompleted()和onError()方法,可使用Action1,subscribe()支持將Action1作為參數傳入,RxJava將會調用它的call方法來接收數據,代碼如下:

justObservable.subscribe(new Action1() {

      @Override
      public void call(String s) {
          LogUtil.log(s);
  }
});

以上就是RxJava最簡單的用法。


Rxjava的優(yōu)勢---簡潔(舉例說明)

Rxjava的最大優(yōu)勢是代碼簡潔。這里的簡潔不是說代碼量少,是說,隨著業(yè)務邏輯的增加,代碼的可讀性依然保持良好。沒有之前的多層回調,一層一層的縮進的代碼結構。具體就是,沒增加一層回調或者功能,都可以用Rxjava的方法,連續(xù)點點點,增加功能。

看到這里,我也不知道我寫的是否簡單明了,也許你會想,“哎呀,寫個異步的東西,怎么這么麻煩,為什么不用Thread+Handler呢”,那你就錯了,RxJava也以代碼的簡潔深受廣大用戶喜愛,簡潔不能理解為代碼量少,而是隨著邏輯的復雜,需求的更改,代碼可依然能保持極強的閱讀性,舉個簡單的例子(前方高能預警~~~),領導要我從數據庫的用戶表查找出所有用戶數據,我二話不說拿出心儀的RxJava就寫:

Observable.create(new Observable.OnSubscribe>() {

      @Override
      public void call(Subscriber> subscriber) {
          List userList = null;
          ···
          //從數據庫獲取用戶表數據并賦給userList
          ···
          subscriber.onNext(userList);
        }
    }).subscribe(new Action1>() {

      @Override
      public void call(List users) {
      //獲取到用戶信息列表
    }

});

但是,領導突然又不想要所有用戶了,只要名字叫“小明”的用戶,行吧,領導最大,我改(假設名字唯一):

Observable.create(new Observable.OnSubscribe>() {

      @Override
      public void call(Subscriber> subscriber) {
          List userList = null;
          ···
          //從數據庫獲取用戶表數據并賦給userList
          ···
          subscriber.onNext(userList);
      }

    }).flatMap(new Func1, Observable>() {

      @Override
      public Observable call(List users) {
          return Observable.from(users);
      }

    }).filter(new Func1() {

      @Override
      public Boolean call(User user) {
          return user.getName().equals("小明");
      }
    }).subscribe(new Action1() {

        @Override
        public void call(User user) {
          //拿到謎之小明的數據
    }
});

搞定,這時候領導又說,我不要小明了,我要小明的爸爸的數據,(坑爹啊~~),我繼續(xù)改:

Observable.create(new Observable.OnSubscribe>() {

        @Override
        public void call(Subscriber> subscriber) {

            List userList = null;
            ···
            //從數據庫獲取用戶表數據并賦給userList
            ···
            subscriber.onNext(userList);
        }

   }).flatMap(new Func1, Observable>() {

        @Override
        public Observable call(List users) {
              return Observable.from(users);
        }
        }).filter(new Func1() {

        @Override
        public Boolean call(User user) {
            return user.getName().equals("小明");
        }

     }).map(new Func1() {

        @Override
        public User call(User user) {
        //根據小明的數據user從數據庫查找出小明的父親user2
              return user2;
        }

     }).subscribe(new Action1() {

        @Override
        public void call(User user2) {
        //拿到謎之小明的爸爸的數據
        }
});

搞定,“還想怎么改?領導請說···”。

以上例子,涉及到幾個操作符,初學者可能無法理解,但是無所謂,這不是重點,我的目的只是為了向你展示RxJava在需求不斷變更、邏輯愈加復雜的情況下,依舊可以保持代碼簡潔、可閱讀性強的一面,沒有各種回調,也沒有謎之縮進!

總結

看了以上所講,如果你已經愛上了RxJava,如果你已經全部理解,我確信,你已經跨入RxJava的大門,剩下的只是時間的問題以及如何在實際開發(fā)場景中去應用的問題,那么下篇文章,我將繼續(xù)講解RxJava中各種強大的操作符,并盡量以實際開發(fā)過程中遇到的問題作為例子,提升自己的同時,幫助初學者迅速上手RxJava,如有寫的不好的地方,還請見諒,真心歡迎各路大神指點,探討相關技術。

歡迎繼續(xù)收看:RxJava入門與提高-Subject篇(2)

作者:ZhangYushui

來源:簡書

著作權歸作者所有。商業(yè)轉載請聯系作者獲得授權,非商業(yè)轉載請注明出處。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 本篇文章介主要紹RxJava中操作符是以函數作為基本單位,與響應式編程作為結合使用的,對什么是操作、操作符都有哪些...
    嘎啦果安卓獸閱讀 2,976評論 0 10
  • 作者寄語 很久之前就想寫一個專題,專寫Android開發(fā)框架,專題的名字叫 XXX 從入門到放棄 ,沉淀了這么久,...
    戴定康閱讀 7,730評論 13 85
  • 我從去年開始使用 RxJava ,到現在一年多了。今年加入了 Flipboard 后,看到 Flipboard 的...
    Jason_andy閱讀 5,746評論 7 62
  • 注:只包含標準包中的操作符,用于個人學習及備忘參考博客:http://blog.csdn.net/maplejaw...
    小白要超神閱讀 2,366評論 2 8
  • 我來不及認真地年輕,待明白過來時,只能選擇認真地老去。 ——三毛
    Sophie0418閱讀 264評論 0 1

友情鏈接更多精彩內容