[Android]RxJava的簡單介紹和基本使用(一)__Java

來源:互聯網
上載者:User

前言

RxJava以及RxAndroid(https://github.com/ReactiveX/RxAndroid)已經火了一段時間,這裡簡單的介紹一下它們。RxJava 在 GitHub 首頁上的自我介紹是 "a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一個在 Java VM 上使用可觀測的序列來組成非同步、基於事件的程式的庫)。實際上,它已經變成了一個專為 Android 而生的響應式第三方庫,主要是因為它是第一個全方位可用於 Java 支援的響應式第三方庫。RxJava 2 保留了我們需要在 Android 上支援的所有 Java 版本。關鍵字:響應式編程非同步

歸結起來,它由三個主要的部分組成:

1.用於表示資料來源的一組類
2.用於偵聽資料來源的一組類
3.用於修改與合并資料的一組方法
當您開始偵聽資料來源的時候,它將開始或者停止執行某些操作。您可以將其想象為一種網路請求,除非您開始對網路回應進行偵聽,否則的話這個網路請求將永遠不會觸發。並且如果您在資料來源任務完成之前取消了對資料來源的訂閱,那麼它很可能會取消這個網路請求。

這些操作可以是同步的,也可以是非同步,因此您可以構造出一個類似網路請求的操作,它會在某個代碼塊當中運行,但是卻是運行在後台線程之上的。或者,它也可以是完全非同步,就像我們在 Android 中彈出 Activity 或者單擊 UI 當中的某個組件,這些都可以被視為非同步作業。

通常情況下,一個網路請求只會產生一條回應,但是只要您的 UI 還存在於那裡,即便您只訂閱了一個按鈕,您會發現,按鈕的單擊事件流卻可能是無限的。此外,它們所產生的回應也可能是空的,因此這種類型的資料來源實際上只有兩種功能:成功或者失敗,它不會產生任何的資料。您可以將其視為類似寫入資料庫或者寫入檔案的操作。它實際上並不會返回相關的回應或者資料;它要麼成功完成、要麼失敗。這種完成、失敗的回應程式面是由 RxJava 當中的資料來源,結合那些所謂「終端事件 (terminal event)」而構建的。這類似於那些可以正常返回、也可以拋出異常的方法。

這種響應也有可能永遠不會終止。讓我們回到之前的按鈕點擊操作樣本來,如果我們將按鈕點擊事件構建為資料來源,那麼只要您的這個 UI 還存在,那麼這個響應永遠都不會結束。只有當 UI 消失,並且您取消了該按鈕點擊事件的訂閱之後,才可能會結束。在此之前,它將永遠不會進入到完成狀態。

這一切相當於實現了傳統的觀察者模式。我們有某些可以產生資料的組件,然後我們只想知道它們所產生的資料是什麼,因此我們所要做的僅僅只是觀察而已。所以我們可以添加一個監聽器,當事件發生的時候就收到相應的通知。


基本使用

前面囉嗦了一大堆,感覺好像沒什麼卵用。直接進入正題,對於程式猿來說,代碼比文字更容易理解吧。

build.gradle 中請依賴,

compile 'io.reactivex.rxjava2:rxandroid:2.0.1'// Because RxAndroid releases are few and far between, it is recommended you also// explicitly depend on RxJava's latest version for bug fixes and new features.compile 'io.reactivex.rxjava2:rxjava:2.0.1'
private void createFlowable(final String str) {        Flowable<String> flowable = Flowable.create(new FlowableOnSubscribe<String>() {            @Override            public void subscribe(FlowableEmitter<String> e) throws Exception {                //onNext方法就是發射一個任務:比如本例子中的開燈動作                e.onNext(str);                //事件完成後調用                e.onComplete();            }        }, BackpressureStrategy.BUFFER); //支援背壓,不丟棄資料的處理方式        Subscriber<String> subscriber = new Subscriber<String>() {            @Override            public void onSubscribe(Subscription s) {                Log.d(TAG, "---onSubscribe---");                //必須設定可請求的次數,否則不會執行onNext和onComplete方法                s.request(Long.MAX_VALUE);            }            @Override            public void onNext(String s) {                Log.d(TAG, "---onNext-->" + s);                Toast.makeText(mContext, s, Toast.LENGTH_SHORT).show();            }            @Override            public void onError(Throwable t) {                Log.e(TAG,"---onError-->",t);            }            @Override            public void onComplete() {                Log.d(TAG, "---onComplete-->the light is on");            }        };        //subscribe:發射源執行這個事件        flowable.subscribe(subscriber);    }
createFlowable("turn the light on!");執行
 
04-20 13:43:08.904 12293-12293/org.jan.rxandroiddemo D/SimpleFunc1Activity: ---onSubscribe---04-20 13:43:08.904 12293-12293/org.jan.rxandroiddemo D/SimpleFunc1Activity: ---onNext-->turn the light on!04-20 13:43:08.944 12293-12293/org.jan.rxandroiddemo D/SimpleFunc1Activity: ---onComplete-->the light is on
Flowable大意是流動性的,我們可以把它想象成某種事件隊列的發射源。 建立一個Flowable發射源,假設程式猿加班回家開燈這樣的一件事來說,開燈然後燈亮,開燈的動作組合由Flowable來安排執行(subscribe)。 Subscriber 可以想象成一個事件的處理和響應接收器。開燈動作之後,如電流通過燈泡的物理反應,就是在這個對象裡的方法裡(onNext)處理。








是不是覺得寫法有些複雜啊,Rxjava中有個just的方法,會自動根據你的輸入參數自行調用onNext方法哦

來一波代碼示意

  private void createSimpleFlowable(String params) {        Flowable.just(params).subscribe(new Consumer<String>() {            @Override            public void accept(String s) throws Exception {                Log.i(TAG,"---accept-->"+s);                Toast.makeText(mContext, s, Toast.LENGTH_SHORT).show();            }        });    }
 調用一下 createSimpleFlowable("turn the light off!");
04-20 14:15:37.864 18583-18583/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---accept-->turn the light off!


變換入門

哈哈哈,我們還可以在輸入到輸出的過程中對資料做變換操作,什麼意思。上代碼。

      Flowable.just("hello! RxJava2")                .subscribe(new Consumer<String>() {                    @Override                    public void accept(String s) throws Exception {                        Log.i(TAG,"Android-jan:"+s);                    }                });
04-20 14:37:07.634 15173-15173/org.jan.rxandroiddemo I/SimpleFunc1Activity: Android-jan:hello! RxJava2

操作符

1.map轉換,map函數會返回一個被轉換後的Flowable對象哦

private void map(String str) {        Flowable.just(str).map(new Function<String, String>() {            @Override            public String apply(String s) throws Exception {                //這兒我們做點小動作                return s+"下午3點";            }        }).subscribe(new Consumer<String>() {            @Override            public void accept(String s) throws Exception {                Log.i(TAG,"---accept-->"+s);                Toast.makeText(mContext, s, Toast.LENGTH_SHORT).show();            }        });    }

調用我的方法:map("2017年4月20日"); 看看列印了什麼。其實你心中早有結果。

04-20 15:44:48.834 25851-25851/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---accept-->2017年4月20日下午3點

再來一波,看看能不能雙map執行,

/**     * 把輸入參數str的hashcode轉換成String 並且列印出來     * @param str     */    private void map2(String str) {        Flowable.just(str).map(new Function<String, Integer>() {            @Override            public Integer apply(String s) throws Exception {                return s.hashCode();            }        }).map(new Function<Integer, String>() {            @Override            public String apply(Integer integer) throws Exception {                return integer.toString();            }        }).subscribe(new Consumer<String>() {            @Override            public void accept(String s) throws Exception {                Log.i(TAG,s);                Toast.makeText(mContext, s, Toast.LENGTH_SHORT).show();            }        });    }
沒錯,列印結果是正確的。

2.fromIterable方法,如果我現在手裡有一組列表,我要通過Flowable把它射出去 ,我來教你

   List<Integer> list = new ArrayList<>();        list.add(10);        list.add(15);        list.add(20);        list.add(256);        list.add(1000);        Flowable.fromIterable(list).subscribe(new Consumer<Integer>() {            @Override            public void accept(Integer integer) throws Exception {                Log.i(TAG,"---from->"+integer);            }        });

列印結果:

04-20 16:38:16.404 24914-24914/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---from->1004-20 16:38:16.404 24914-24914/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---from->1504-20 16:38:16.404 24914-24914/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---from->2004-20 16:38:16.404 24914-24914/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---from->25604-20 16:38:16.404 24914-24914/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---from->1000

3.flatMap操作符,感覺跟map有點像,實際上比map厲害了,主要用來破除嵌套結構。先不用著急,咱們可以先確定的事是 它可以把一個 Flowable 轉換成另一個 Flowable。

  List<Integer> list = new ArrayList<>();        list.add(10);        list.add(15);        list.add(20);        list.add(256);        list.add(1000);        Flowable.just(list).flatMap(new Function<List<Integer>, Publisher<String>>() {            @Override            public Publisher<String> apply(List<Integer> integers) throws Exception {                //這段代碼意思不重要,重要的是,它能幫你轉換你的輸入參數,並返回一個Publisher發射源:Flowable                List<String> strs = new ArrayList<String>();                for(Integer integer:integers){                    strs.add(String.valueOf(integer));                }                return Flowable.fromIterable(strs);            }        }).subscribe(new DefaultSubscriber<String>() {            @Override            public void onNext(String s) {                //這裡接收的不是Integer類型了,已經處理成String類型                Log.i(TAG,"---onNext-->"+s);            }            @Override            public void onError(Throwable t) {                Log.e(TAG,"---onError-->",t);            }            @Override            public void onComplete() {                Log.i(TAG,"---onComplete---");            }        });
列印結果:

04-20 17:28:39.044 3101-3101/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---onNext-->1004-20 17:28:39.044 3101-3101/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---onNext-->1504-20 17:28:39.044 3101-3101/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---onNext-->2004-20 17:28:39.044 3101-3101/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---onNext-->25604-20 17:28:39.044 3101-3101/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---onNext-->100004-20 17:28:39.044 3101-3101/org.jan.rxandroiddemo I/SimpleFunc1Activity: ---onComplete---
如果你沒完全理解的話,請轉 關於RxJava的from()和 flatMap()方法 

4.filter操作符,過濾的意思,假設我們要過濾一組數組,來個條件吧

  Integer[] array = {1,2,3,5,6,4,0};        Flowable.fromArray(array).filter(new Predicate<Integer>() {            @Override            public boolean test(Integer integer) throws Exception {                //把數組中大於4的元素過濾出來                return integer.intValue()>4;            }        }).subscribe(new Consumer<Integer>() {            @Override            public void accept(Integer integer) throws Exception {                Log.i(TAG,"filter->integer="+integer);            }        });
列印結果:

04-20 17:42:33.764 3101-3101/org.jan.rxandroiddemo I/SimpleFunc1Activity: filter->integer=504-20 17:42:33.764 3101-3101/org.jan.rxandroiddemo I/SimpleFunc1Activity: filter->integer=6


5.take操作符,限制發射源發射的數量,take(3)意思就是只能發射3次元素

 Integer[] array = {1,2,7,5,6,4,0};        Flowable.fromArray(array).take(3).subscribe(new Consumer<Integer>() {            @Override            public void accept(Integer integer) throws Exception {                Log.i(TAG,"take->integer="+integer);            }        });
列印結果:

04-20 17:49:54.784 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: take->integer=104-20 17:49:54.784 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: take->integer=204-20 17:49:54.784 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: take->integer=7


6.doOnNext方法:如果我們想在訂閱者接收到資料前幹點事情,比如記錄日誌。

 Integer[] array = {1,2,3,5,6,4,0};        Flowable.fromArray(array).doOnNext(new Consumer<Integer>() {            @Override            public void accept(Integer integer) throws Exception {                //在訂閱之前可以進行日誌記錄                Log.i(TAG,"doOnNext->integer="+integer);            }        }).subscribe(new Consumer<Integer>() {            @Override            public void accept(Integer integer) throws Exception {                Log.i(TAG,"subscribe->integer="+integer);            }        });
列印結果:

04-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: doOnNext->integer=104-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: subscribe->integer=104-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: doOnNext->integer=204-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: subscribe->integer=204-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: doOnNext->integer=304-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: subscribe->integer=304-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: doOnNext->integer=504-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: subscribe->integer=504-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: doOnNext->integer=604-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: subscribe->integer=604-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: doOnNext->integer=404-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: subscribe->integer=404-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: doOnNext->integer=004-20 17:51:57.324 22016-22016/org.jan.rxandroiddemo I/SimpleFunc1Activity: subscribe->integer=0

今天就先寫這麼些吧,反正就是基礎使用,各位看官先消化消化吧。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.