我所理解的RxJava——上手其實很簡單(一)

前言

相信各位看官對RxJava早有耳聞,那么關于什么是RxJava我就不再贅述了,不知道的可自行百度。如果你已經大致了解過什么是RxJava,想開始學習,那么本文不失為你良好的選擇,為什么這么說呢,因為我也是剛學幾天,正所謂“知己知彼,百戰不殆”。網上流傳,RxJava的入門門檻高,而經過我這幾天的學習,我反而不那么認為,精通我不敢說,但入門確實也不難,不信?我先來個簡單的例子預熱一下。

先創建個數據發射源,很好理解,就是發射數據用的:

   Observable<String> sender = Observable.create(new Observable.OnSubscribe<String>() {
         
           @Override
            public void call(Subscriber<? super String> subscriber) {

                subscriber.onNext("Hi,Weavey!");  //發送數據"Hi,Weavey!"
            }
        });

再創建個數據接收源,同理,接收數據用的:

   Observer<String> receiver = new Observer<String>() {
           
            @Override
            public void onCompleted() {

                //數據接收完成時調用
            }

            @Override
            public void onError(Throwable e) {

                //發生錯誤調用
            }

            @Override
            public void onNext(String s) {

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

好了,將發射源和接收源關聯起來:

  sender.subscribe(receiver);

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


論概念的重要性

網上關于RxJava的博文也有很多,我也看過許多,其中不乏有優秀的文章,但絕大部分文章都有一個共同點,就是側重于講RxJava中各種強大的操作符,而忽略了最基本的東西——概念,所以一開始我也看的一臉懵逼,看到后面又忘了前面的,腦子里全是問號,這個是什么,那個又是什么,這兩個長得怎么那么像。舉個不太恰當的例子,概念之于初學者,就像食物之于人,當你餓了,你會想吃面包、牛奶,那你為什么不去吃土呢,因為你知道面包牛奶是用來干嘛的,土是用來干嘛的。同理,前面已經說過,RxJava無非是發送數據與接收數據,那么什么是發射源,什么是接收源,這就是你應該明確的事,也是RxJava的入門條件之一,下面就依我個人理解,對發射源和接收源做個歸類,以及RxJava中頻繁出現的幾個“單詞”解釋一通,說的不好還請海涵,歡迎補充。


基本概念

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

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

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

Subscriber:“訂閱者”,也是接收源,那它跟Observer有什么區別呢?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的創建
    1.使用create( ),最基本的創建方式:
normalObservable = Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        subscriber.onNext("create1"); //發射一個"create1"的String
        subscriber.onNext("create2"); //發射一個"create2"的String
        subscriber.onCompleted();//發射完成,這種方法需要手動調用onCompleted,才會回調Observer的onCompleted方法
    }});

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

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

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

List<String> list = new ArrayList<>();
list.add("from1");
list.add("from2");
list.add("from3");
fromObservable = Observable.from(list);  //遍歷list 每次發送一個
/** 注意,just()方法也可以傳list,但是發送的是整個list對象,而from()發送的是list的一個item** /

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

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

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

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

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

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

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

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

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

repeatObservable = Observable.just("repeatObservable").repeat(3);//重復發射3次
  • Observer的創建
mObserver = new Observer<String>() {
    @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,我們就可以隨便玩了,任取一個已創建的Observable和Observer關聯上,即形成一個RxJava的例子,如:

justObservable.subscribe(mObserver);

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

justObservable.subscribe(new Action1<String>() {
      @Override
      public void call(String s) {

            LogUtil.log(s);
       }});

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

       Observable.create(new Observable.OnSubscribe<List<User>>() {
            @Override
            public void call(Subscriber<? super List<User>> subscriber) {
                List<User> userList = null;
                ···
                //從數據庫獲取用戶表數據并賦給userList
                ···
                subscriber.onNext(userList);
            }
        }).subscribe(new Action1<List<User>>() {
            @Override
            public void call(List<User> users) {
                
                //獲取到用戶信息列表
            }
        });

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

      Observable.create(new Observable.OnSubscribe<List<User>>() {
            @Override
            public void call(Subscriber<? super List<User>> subscriber) {
                List<User> userList = null;
                ···
                //從數據庫獲取用戶表數據并賦給userList
                ···
                subscriber.onNext(userList);
            }
        }).flatMap(new Func1<List<User>, Observable<User>>() {
            @Override
            public Observable<User> call(List<User> users) {
                return Observable.from(users);
            }
        }).filter(new Func1<User, Boolean>() {
            @Override
            public Boolean call(User user) {
                return user.getName().equals("小明");
            }
        }).subscribe(new Action1<User>() {
            @Override
            public void call(User user) {
                //拿到謎之小明的數據
            }
        });

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

  Observable.create(new Observable.OnSubscribe<List<User>>() {
            @Override
            public void call(Subscriber<? super List<User>> subscriber) {
                List<User> userList = null;
                ···
                //從數據庫獲取用戶表數據并賦給userList
                ···
                subscriber.onNext(userList);
            } 
       }).flatMap(new Func1<List<User>, Observable<User>>() {
            @Override
            public Observable<User> call(List<User> users) {
                return Observable.from(users);
            }
        }).filter(new Func1<User, Boolean>() {
            @Override
            public Boolean call(User user) {
                return user.getName().equals("小明");
            }
        }).map(new Func1<User, User>() {
            @Override
            public User call(User user) { 
                //根據小明的數據user從數據庫查找出小明的父親user2
                return user2;
            }
        }).subscribe(new Action1<User>() {
            @Override
            public void call(User user2) {
              //拿到謎之小明的爸爸的數據
            }
        });

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


總結

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


本猿已轉行,勿念。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,908評論 2 372

推薦閱讀更多精彩內容