【Android】RxJava的使用

參考:
給 Android 開發(fā)者的 RxJava 詳解
(本文部分內(nèi)容引用自該博客)

RxJava的設(shè)計模式:監(jiān)聽者模式。

成員:

觀察者:Observer;
被觀察者:Observable;
訂閱(或注冊):subscribe()。

一個簡單的訂閱實現(xiàn):

         // 觀察者
        Observer observer = new Observer<String>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(String string) {
                Log.e("RxJava",string);
            }
        };
        //  被觀察者
        Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("xxx");
            }
        });
        // 訂閱 (被觀察者訂閱了觀察者-。-)
        observable.subscribe(observer);

觀察者Observer 的擴(kuò)展

  • Subscriber
class Subscriber<T> implements Observer<T>, Subscription

看源碼可知Subscribe增加了onStart()方法,Subscription增加了unsubscribe()、isUnsubscribed()方法。

onStart() :這是Subscriber增加的方法。它會在 subscribe 剛開始,而事件還未發(fā)送之前被調(diào)用,可以用于做一些準(zhǔn)備工作,例如數(shù)據(jù)的清零或重置。這是一個可選方法,默認(rèn)情況下它的實現(xiàn)為空。需要注意的是,如果對準(zhǔn)備工作的線程有要求(例如彈出一個顯示進(jìn)度的對話框,這必須在主線程執(zhí)行),onStart()就不適用了,因為它總是在 subscribe 所發(fā)生的線程被調(diào)用,而不能指定線程。要在指定的線程來做準(zhǔn)備工作,可以使用doOnSubscribe()方法,具體可以在后面的文中看到。

unsubscribe()、isUnsubscribed() :用于取消訂閱。在這個方法被調(diào)用后,Subscriber將不再接收事件。一般在這個方法調(diào)用前,可以使用isUnsubscribed()先判斷一下狀態(tài)。注意要在關(guān)閉頁面時解除綁定避免內(nèi)存泄漏。

被觀察者Observable的擴(kuò)展

just()
Observable observable2 = Observable.just("Hello", "World");
----------------------------------------------------------------------------------------------------
from()
String [] words = {"Hello", "World"};
Observable observable3 = Observable.from(words);
----------------------------------------------------------------------------------------------------
from()
List<String> list = new ArrayList<String>();
list.add("Hellow");
list.add("Wrold");
Observable observable4 = Observable.from(list);
----------------------------------------------------------------------------------------------------
看源碼可知just最終會將字符串、對象轉(zhuǎn)換成一個list調(diào)用from最終調(diào)用Observable.create()方法,遍歷輸出Hello、World。

Action (一個沒有返回參數(shù)的接口)

下面來看一段源碼:


RxJava源碼
通過源碼分析可知Action的內(nèi)部其實是實現(xiàn)了new Subscriber<T>()的3個方法的實現(xiàn),通過傳入接口Action1調(diào)用call()方式讓用戶自定義實現(xiàn)內(nèi)容。

Action實現(xiàn)具體代碼:

  Observable.just("hello").subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                Log.e("RxJava",s);
            }
        });

注意:call() 是無返回值的。

Map (帶返回參數(shù)的接口)

舉個栗子:

public class UserBean {
    String name = "carl";
    int age = 18;
}

如何獲取UserBean 對象的name值呢?

UserBean userBean = new UserBean();
        Observable.just(userBean)
                .map(new Func1<UserBean, String>() {
                    @Override
                    public String call(UserBean userBean) {
                        return userBean.name;
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String name) {
                        Log.e("UserBean", "" + name);
                    }
                });
通過map操作符返回UserBean對象,獲取到userBean.name的值。

flatMap concatMap(獲取list數(shù)組對象的操作符)

舉個栗子:


public class UserBean {
    String name = "carl";
    int age = 18;
    List<Order> orderList;
}

public class Order {
    String money = "100元";
}

UserBean中有一個集合為orderList,如何遍歷獲取到list中Order的數(shù)據(jù)呢?
        // 初始化orderList的數(shù)據(jù)
        UserBean userBean1 = new UserBean();
        List<Order> orderList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Order order = new Order();
            order.money = "100" + i + "yuan";
            orderList.add(order);
        }
        userBean1.orderList = orderList;
        // RxJava應(yīng)用
        Observable.just(userBean1)
                //  flatMap處理Order的List,通過返回userBean,在用Observable.from(list)處理list數(shù)據(jù)
                .flatMap(new Func1<UserBean, Observable<Order>>() {
                    @Override
                    public Observable<Order> call(UserBean userBean) {
                        return Observable.from(userBean.orderList);
                    }
                })
                //   再用map獲取到list中每一個item的數(shù)據(jù)
                .map(new Func1<Order, String>() {
                    @Override
                    public String call(Order order) {
                        return order.money;
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.e("flatMap", s);
                    }
                });

輸出結(jié)果為:
1000yuan
1001yuan
1002yuan
1003yuan
1004yuan

flatMap示意圖

由上圖可以看出Student1、Student2經(jīng)過flatMap后,按順序依次經(jīng)歷了Observable1、Observable2,分別轉(zhuǎn)化為Course。最后按順序得到Course1、Course2、Course3、Course4、Course5、Course6,其中1-3由Student1得到,4-6由Student2得到。

注意:FlatMap對這些Observables發(fā)射的數(shù)據(jù)做的是合并(merge)操作,因此它們可能是交錯的。也就說,傳入的順序可能跟出來的順序不一樣。

如果要保證順的的話,可以使用concatMap。

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

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容