【Android】RxJava的使用

2017-11-25  本文已影响0人  喝茶就困

参考:
给 Android 开发者的 RxJava 详解
(本文部分内容引用自该博客)

RxJava的设计模式:监听者模式。

成员:

观察者:Observer;
被观察者:Observable;
订阅(或注册):subscribe()。

一个简单的订阅实现:

         // 观察者
        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 的扩展

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

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

onStart() :这是Subscriber增加的方法。它会在 subscribe 刚开始,而事件还未发送之前被调用,可以用于做一些准备工作,例如数据的清零或重置。这是一个可选方法,默认情况下它的实现为空。需要注意的是,如果对准备工作的线程有要求(例如弹出一个显示进度的对话框,这必须在主线程执行),onStart()就不适用了,因为它总是在 subscribe 所发生的线程被调用,而不能指定线程。要在指定的线程来做准备工作,可以使用doOnSubscribe()方法,具体可以在后面的文中看到。

unsubscribe()、isUnsubscribed() :用于取消订阅。在这个方法被调用后,Subscriber将不再接收事件。一般在这个方法调用前,可以使用isUnsubscribed()先判断一下状态。注意要在关闭页面时解除绑定避免内存泄漏。

被观察者Observable的扩展

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最终会将字符串、对象转换成一个list调用from最终调用Observable.create()方法,遍历输出Hello、World。

Action (一个没有返回参数的接口)

下面来看一段源码:


RxJava源码
通过源码分析可知Action的内部其实是实现了new Subscriber<T>()的3个方法的实现,通过传入接口Action1调用call()方式让用户自定义实现内容。

Action实现具体代码:

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

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

Map (带返回参数的接口)

举个栗子:

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数组对象的操作符)

举个栗子:


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

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

UserBean中有一个集合为orderList,如何遍历获取到list中Order的数据呢?
        // 初始化orderList的数据
        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应用
        Observable.just(userBean1)
                //  flatMap处理Order的List,通过返回userBean,在用Observable.from(list)处理list数据
                .flatMap(new Func1<UserBean, Observable<Order>>() {
                    @Override
                    public Observable<Order> call(UserBean userBean) {
                        return Observable.from(userBean.orderList);
                    }
                })
                //   再用map获取到list中每一个item的数据
                .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);
                    }
                });

输出结果为:
1000yuan
1001yuan
1002yuan
1003yuan
1004yuan

flatMap示意图

由上图可以看出Student1、Student2经过flatMap后,按顺序依次经历了Observable1、Observable2,分别转化为Course。最后按顺序得到Course1、Course2、Course3、Course4、Course5、Course6,其中1-3由Student1得到,4-6由Student2得到。

注意:FlatMap对这些Observables发射的数据做的是合并(merge)操作,因此它们可能是交错的。也就说,传入的顺序可能跟出来的顺序不一样。

如果要保证顺的的话,可以使用concatMap。

上一篇下一篇

猜你喜欢

热点阅读