RxJava1.x學習

前言:

    作爲一個小菜鳥,以前都沒有用過RxJava,但這都絲毫不影響我在這裏BB。以前寫個異步就是new Thread()+new Handler();或者是使用new AsyncTask();來實現一個異步操作。大清早起來,就準備研究這個RxJava,想看看這個是個什麼玩意;

    首先呢,學習一門新東西要先了解他,於是乎我就拿出我的看家本領“百度一下”;百度了一些文章,看着特別棒,講解的也很詳細,可是我TM就是不懂啊!


    抱着“我的智商是沒有問題的”這一想法,我又細心的看了兩三遍,捋了捋思路,親自動手敲了下代碼,然後發現:


    大佬們寫的東西總是站在大佬的角度出發的:哪怕是大佬已經想到了新手可能要比自己略遜一點,但大佬並沒有想到新手原來如此的笨(比如我),於是我在學的過程中就想寫一些小菜鳥們的入門寶典(從入門到放棄愛不釋手);

    不多BB了,下面整點乾貨!


引入依賴:

    不把庫引進來怎麼用!

    ·AndroidStudio的小夥伴們可以:

RxJava:
    compile 'io.reactivex:rxjava:1.0.14'
    compile 'io.reactivex:rxandroid:1.0.1'
RxBinding:
  compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'//這個是另一個庫,先在這裏放着,初學不用理這個,引上邊兩個就可以了!
    ·Eclipse的小夥伴們可以:

換AndroidStudio吧!

鏈接: https://pan.baidu.com/s/14jRRvsTRZQjtc8KlZw0rZg 密碼: tyyh

買一贈一,順便還換個開發工具!

    多說一句,因爲我學的時候去GitHub看了一下,版本已經更新到了2.0,當時引入的是2.0的依賴,發現問題大了,好多方法都不一樣了,多了一些東西,看得我濛濛的;


我又重新引的1.x版本,初學者嘛,學會了1之後在延伸到2就容易很多了;除了RxJava之外,上面提到的RxBinding也是這樣,本身更新到了2.0版本,也是有一些方法發生了改變。我這裏引入的是一個0.4的版本;

庫引進來了,到了最關鍵的怎麼用了!你以爲我會直接上代碼?NoNoNo!先簡單介紹幾個有趣的概念,後面都會用的到的!

重要概念:

    ·響應式編程

    RxJava 是一個響應式編程框架,採用觀察者設計模式。至於什麼事觀察者設計模式,可以自行百度;

    ·Subscriber

    觀察者,接受者,可接收ObservableSubject發射的數據,異步中就是再這裏接收數據並處理,一般最終會設置運行在ui線程;

    ·Observable

    被觀察者,發射源,數據處理和數據發送是在這裏進行的,這裏涵蓋了好多東西,包含線程,類型轉換,網絡請求等;

    ·FuncX

    RxJava中封裝的一個類,X代表的是參數個數;這個類用來指定有返回值的對象類型回調;

    ·ActionX

    作用和Func相同,只是這個類沒有返回值;

    ·操作符

    操作符有很多,指的是在進行響應式編程的過程中用到的一些工具方法,用來滿足各類需求;後面會介紹一些重要的操作符,其他的會附上一個連接自行研究;

    ·Scheduler

    線程控制。我們在使用RxJava時無可避免的就是爲了解決異步的問題,這個類爲我們提供了線程控制,如何在RxJava中自由的切換線程,就要看這個類的了;

看到這裏是不是腦海裏多了幾個關鍵字?這幾個關鍵字在以後對RxJava的操作中是非常關鍵的;

代碼部分:

    理解了概念了,就得上點硬貨了,不然光說不練可是假把式!

舉個例子

先從同步開始說起,就是我使用發送者發送一些數據,然後使用接受者收到之後在頁面顯示一下!就是這麼簡單!

    頁面就不用貼出來了,文字描述一下就好了(一個Button,一個TextView)

    在按鈕的監聽事件中,點擊按鈕發送數據

List<String> list = new ArrayList<>();
list.add("Hello!");
list.add("My name is HuJun!");
list.add("And you?");
list.add("How are you?");
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //第一種方法:使用create()創建一個Observable對象,並且執行相應的操作,發送一些數據到觀察者中;
        Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("hello1");
                subscriber.onNext("hello2");
                subscriber.onNext("hello3");
                subscriber.onNext("hello4");
                subscriber.onNext("hello5");
                subscriber.onCompleted();
            }
        }).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                Log.d("TAG", "call: ");
                tv.append("\n"+s);
            }
        });

        //第二種方法:from方法用於解析一個list,內置創建了一個被觀察者對象,並且把list中的每一個item
        //發送到了觀察者中,並且自動調用了onCompleted方法;
        Observable.from(list)
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.d("TAG", "call: ");
                        tv.append("\n"+s);
                    }
                });

    }
});
鏈接:Observable的創建
對於被觀察者的創建,根據應用的場景不同,RxJava給我們提供了許多方法,這裏就不一一贅述了,放個連接,可以瞭解一下,這部分也是我轉載的。
原文很長,被我拆分了一下,拆成了幾個短一點的文章;

上述呢,就是RxJava最簡單的一個使用方式;你以爲這就結束了嗎?學完這個你會發現:然卵用???


我寫RxJava的最開始的意圖是爲了更好的實現異步操作,這個樣子那裏有半點異步的樣子了;

那我就來舉個異步的栗子算了;

舉例子之前,先說一下RxJava中關於異步的實現;

線程調度器--Scheduler中控制線程依賴一個Scheduler 對象,Scheduler 對象分爲一下幾類:

Schedulers.immediate()直接在當前線程中運行,相當於不指定線程,這也是RxJava默認的線程方式;
Schedulers.newThread()啓用新線程,並且在新線程中執行操作;
Schedulers.io()I/O 操作(讀寫文件、讀寫數據庫、網絡信息交互等)所使用的 Scheduler;區別在於 io() 的內部實現是是用一個無數量上限的線程池,可以重用空閒的線程,因此多數情況下 io() 比 newThread() 更有效率。
Schedulers.computation()計算所操作的線程,這個計算指的是CPU密集型計算;
AndroidSchedulers.mainThread()Android獨有的線程,就是所說的Android的主線程,UI線程;

放下手中的刀,我這就舉個異步的例子:


    代入一下場景:

        小明要叫着小李出去打球,可是小李在洗澡,然後小明給小李發消息“我們一會去打球,看到了給我回個消息!”,然後小明就去看電視了,小李洗完澡之後看到消息之後,回消息給小明“完全ojbk!,我們這就走!”,小明收到回覆後關掉電視,一起去打球了;

        分析一下的話,這個流程分爲:小明發出消息->等待小李看到->小李看到之後回覆->小明接收做操作;

        在這個流程中,小明發出消息之後並沒有一直等着小李回覆,也就是並沒有阻塞主線程,而是接着就去看電視了從小明的角度來講,等待小李回消息就是在子線程中運行的,看電視則是運行在主線程;

        這個問題用RxJava怎麼解決呢?

final String xiaoming = "李哥去不去打籃球,看到回覆我一下,我先去看電視!";
Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        subscriber.onNext(xiaoming);
        doWatchTV();//執行看電視操作
        subscriber.onCompleted();
    }
})
        .subscribeOn(Schedulers.newThread())
        .map(new Func1<String, String>() {
            @Override
            public String call(String s) {
                SystemClock.sleep(2000);//過了2000毫秒,小李收到消息
                return s;
            }
        })
        .observeOn(AndroidSchedulers.mainThread())//切換線程
        .subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                //tv.setText("完全ojbk");
                closeTV();//小明收到消息,關閉TV
            }

        });

這看上去確實是一個毫無意義的功能,但是我們可以把他替換爲有意義的功能!比如網絡加載圖片等等;

線程之間的轉換:

observeOn() 指定的是 Subscriber 的線程,而這個 Subscriber 並不是(嚴格說應該爲『不一定是』,但這裏不妨理解爲『不是』)subscribe() 參數中的 Subscriber ,而是 observeOn() 執行時的當前 Observable 所對應的 Subscriber ,即它的直接下級 Subscriber 。換句話說,observeOn() 指定的是它之後的操作所在的線程。因此如果有多次切換線程的需求,只要在每個想要切換線程的位置調用一次 observeOn() 即可。上代碼:

Observable.just(1, 2, 3, 4) // IO 線程,由 subscribeOn() 指定
    .subscribeOn(Schedulers.io())
    .observeOn(Schedulers.newThread())
    .map(mapOperator) // 新線程,由 observeOn() 指定
    .observeOn(Schedulers.io())
    .map(mapOperator2) // IO 線程,由 observeOn() 指定
    .observeOn(AndroidSchedulers.mainThread) 
    .subscribe(subscriber);  // Android 主線程,由 observeOn() 指定
這裏面還用到了一些工具方法,比如.map()方法,這個方法是用來轉換數據時使用的,諸如此類的工具方法有很多,我這裏轉載了一篇比較詳細的,連接貼在這裏,可以去參考學習一下;    這段話我一開始也沒有理解,後來多看了幾遍瞭解了,白話一點的講米就是.subscribeOn()方法指定的是創建操作執行時所在的線程,這個方法只有效這一次(可以這樣理解),如果執行了這個方法之後,後面沒有執行其他的線程切換的方法,那麼之後的所有方法運行就都是存在與這個線程中的,如果之後通過.observeOn()方法修改了指定線程,那麼這個方法之後則都是運行在這個線程上的;

鏈接:RxJava操作符大全

看完這些呢,基本上剩下的關於RxJava的部分就要靠自己摸索了,有興趣也可以翻一翻源碼,看看是怎麼實現的,可能一開始看不懂,看多了就懂了;

文章結尾,再提一個東西,就是開頭也說道過的RxBinding;

都做過監聽的設置,看上邊的代碼不難發現setOnclickLinster的方法寫起來好像不是很美觀;

於是乎有了這麼一個框架,有了它之後,會讓你整個的代碼看上去就是很舒服的響應式的編碼佈局,看着就很爽;

使用方法也很簡單,我這裏舉個和RxJava一起用的栗子,更多例子老規矩也是賦個連接,自己去看;


RxBinding:

    不多BB直接上代碼:
RxView.clicks(findViewById(R.id.btn_iv))
        .throttleFirst( 2 , TimeUnit.SECONDS )//設置兩秒內點擊無效
        .subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {
                Observable.just(urlstr)
                        .map(new Func1<String, Object>() {
                            @Override
                            public Object call(String s) {
                                SystemClock.sleep(2000);
                                return null;
                            }
                        })
                        .subscribeOn(Schedulers.newThread())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Action1<Object>() {
                            @Override
                            public void call(Object object) {
                                tv.setText("完全ojbk!");
                                Log.d(TAG, "call: object-------ok");
                            }
                        });
            }
        });
    這個栗子是響應了一個單擊事件,然後線程睡眠兩秒後通知ui線程更新數據;

具體的多種用法我就把連接放到這裏了,可以去看看

鏈接:RxBinding使用

好了,到這裏就先這樣吧,我要去吃飯了,研究這東西研究了一下午了!


關於作者:

    Name:賈恆飛

    等級:菜雞

    歡迎大佬們支援

    QQ:2757525207

    WX:jy271613

    萌新來騷擾也是可以的;;;;妹子優先哦


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章