Android 淺析 RxJava (一) 使用

weixin_33850890發表於2016-03-22

RxJava


前言

Linus Benedict Torvalds : RTFSC – Read The Fucking Source Code

概括

RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.
RxJava 是一個被設計實現為靈活擴充套件功能的 java 虛擬機器:一個由非同步和事件組成的觀測序列為基礎的程式庫。

It extends the observer pattern to support sequences of data/events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety and concurrent data structures.
它擴充套件了觀察者模式來支援data/events序列和增加了operators來允許你把序列以宣告方式組成在一起並一邊將關注的事情抽象化,比如低執行緒,同步,執行緒安全和併發資料結構。

RxJava 是一個響應式程式設計框架,採用觀察者設計模式。

簡單使用

Step 1:建立Observer

Observer<T> observer = new Observer<T>() {
    @Override
    public void onNext(T s) {}

    @Override
    public void onCompleted() {}

    @Override
    public void onError(Throwable e) {}
};

除了Observer,還有一個內建的Subscriber類實現了Observer的抽象類。Subscriber類對Observer類進行了擴充套件。
它們的實現基本上是一樣的,對於區別,主要有這兩點:

  1. onStart(): 這是 Subscriber 增加的方法。在 subscribe 剛開始,而事件還未傳送之前被呼叫。
  2. unsubscribe(): 這是 Subscriber 所實現的另一個介面 Subscription 的方法,用於取消訂閱。

Step 2:建立Observable

Observable observable = Observable.create(new Observable.OnSubscribe<T>() {
    @Override
    public void call(Subscriber<? super T> subscriber) {
        subscriber.onNext(T);
        subscriber.onCompleted();
    }
});

RxJava 還提供了其它快速建立事件佇列的方法:

Observable observable = Observable.just("Hello", "Hi", "Aloha");

String[] words = {"Hello", "Hi", "Aloha"};
Observable observable = Observable.from(words);

Step 3:Subscribe

observable.subscribe(observer);
// 或者:
observable.subscribe(subscriber);

Observable.subscribe(Subscriber) 的內部實現:

subscriber.onStart();
onSubscribe.call(subscriber);

在接收到訂閱後馬上會開始傳送事件。

不完整定義回撥

subscribe() 還支援不完整定義的回撥,RxJava 會自動根據定義建立出 Subscriber 。

Action1<String> onNextAction = new Action1<String>() {
    // onNext()
    @Override
    public void call(String s) {
        Log.d(tag, s);
    }
};
Action1<Throwable> onErrorAction = new Action1<Throwable>() {
    // onError()
    @Override
    public void call(Throwable throwable) {
        // Error handling
    }
};
Action0 onCompletedAction = new Action0() {
    // onCompleted()
    @Override
    public void call() {
        Log.d(tag, "completed");
    }
};

// 自動建立 Subscriber ,並使用 onNextAction 來定義 onNext()
observable.subscribe(onNextAction);
// 自動建立 Subscriber ,並使用 onNextAction 和 onErrorAction 來定義 onNext() 和 onError()
observable.subscribe(onNextAction, onErrorAction);
// 自動建立 Subscriber ,並使用 onNextAction、 onErrorAction 和 onCompletedAction 來定義 onNext()、 onError() 和 onCompleted()
observable.subscribe(onNextAction, onErrorAction, onCompletedAction);

使用例子

// 將字串陣列 names 中的所有字串依次列印出來:
String[] names = ...;
Observable.from(names)
    .subscribe(new Action1<String>() {
        @Override
        public void call(String name) {
            Log.d(tag, name);
        }
    }
);

Scheduler 執行緒控制

在不指定執行緒的情況下, RxJava 遵循的是執行緒不變的原則,即:在哪個執行緒呼叫 subscribe(),就在哪個執行緒生產事件;在哪個執行緒生產事件,就在哪個執行緒消費事件。如果需要切換執行緒,就需要用到 Scheduler (排程器)。

Observable.just(1, 2, 3, 4)
    .subscribeOn(Schedulers.io()) // 指定 subscribe() 發生在 IO 執行緒
    .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回撥發生在主執行緒
    .subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer number) {
            Log.d(tag, "number:" + number);
        }
    });
  1. subscribeOn(): 指定 subscribe() 所發生的執行緒,即 Observable.OnSubscribe 被啟用時所處的執行緒。或者叫做事件產生的執行緒。
  2. observeOn(): 指定 Subscriber 所執行在的執行緒。或者叫做事件消費的執行緒。

這段程式碼就是說,由 subscribeOn(Schedulers.io()) 的指定,建立的事件內容(1,2,3,4)將由io執行緒發出,而由 observeOn(AndroidScheculers.mainThread()) 的指定,subscriber 數字的 Log 將發生在主執行緒。

進階使用

Operators 操作符

Operators在訊息傳送者Observable和訊息消費者Subscriber之間起到操縱訊息的作用。

map 操作符

Observable.just("Hello, world!")
    .map(new Func1<String, String>() {
        @Override
        public String call(String s) {
            return s + " -Dan";
        }
    })
    .subscribe(s -> System.out.println(s));

當我們在訊息的過程中對訊息進行轉換,最簡單的方法就是使用 map 操作符。
map()函式的特點是:它不一定傳送和原始的Observable一樣的資料型別。

flatMap 操作符

Observable<ArrayList<String>> query(String text);
query("a lot text")
    .flatMap(new Func1<ArrayList<String>, Observable<String>>() {
        @Override
        public Observable<String> call(ArrayList<String> s) {
            return Observable.from(s);
        }
    })
    .subscribe(new Action1<String>() {
        @Override
        public void call(String s) {
            System.out.println(s);
        }
    });

利用 flatMap 操作符可以很方便的將一個 list 的字串分開發出來,在 faltMap 函式內的 Func1跟之前的 Action1 意思一樣,並且返回值是一個新的 Observable 物件。

至於更多的操作符會在未來新增。

最後在說下RxJava 的實際使用意義

  • Observable 和 Subscriber 他們本身就是一個處理事件的通用框架。
  • Observable 和 Subscriber 在它們之間的一系列轉換步驟是相互獨立的。

相關文章