RxJava 简介

第二章:框架介绍:

1:RxJava介绍:

是实现一个异步操作的库,类似于异步任务或handler机制。

RxJava 其实就是提供一套异步编程的 API,这套 API 是基于观察者模式的,而且是链式调用的,所以使用 RxJava 编写的代码的逻辑会非常简洁。

 

RxJava 有以下三个基本的元素:

  1. 被观察者(Observable)
  2. 观察者(Observer)
  3. 订阅(subscribe)

 

首先在 gradle 文件中添加依赖:

implementation 'io.reactivex.rxjava2:rxjava:2.1.4'

implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'

 

 

Demo:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Observable observable = Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter emitter) throws Exception {
                emitter.onNext("a");
                emitter.onNext("b");
                emitter.onNext("c");
                emitter.onComplete();
                Log.e("tag", "产生事件");
            }
        });

        Observer observer = new Observer() {
            @Override
            public void onSubscribe(Disposable d) {
                d.dispose();
                Log.e("tag", "取消订阅 ");

            }

            @Override
            public void onNext(Object o) {
                Log.e("tag", "接收事件:" + o);
            }

            @Override
            public void onError(Throwable e) {

                Log.e("tag", " 数据处理出错");
            }

            @Override
            public void onComplete() {
                Log.e("tag", "数据处理完成");

            }
        };
        observable.map(new Function() {
            @Override
            public Object apply(Object o) throws Exception {
                return o.toString();
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
    }


 

·被观察者发送的事件有以下几种,总结如下表:

 

总结如下图:

 

1. 创建操作符

以下就是讲解创建被观察者的各种操作符。

 

1.1 create()

方法预览:

public static <T> Observable<T> create(ObservableOnSubscribe<T> source)

有什么用:

创建一个被观察者

Observable observable = Observable.create(new ObservableOnSubscribe() {
    @Override
    public void subscribe(ObservableEmitter emitter) throws Exception {
        emitter.onNext("a");
        emitter.onNext("b");
        emitter.onNext("c");
        emitter.onComplete();
        Log.e("tag", "产生事件");
    }
});

上面的代码非常简单,创建 ObservableOnSubscribe 并重写其 subscribe 方法,就可以通过 emitter发射器向观察者发送事件。 

 

 

然后创建一个观察者,来验证这个被观察者是否成功创建。

 

 

 

 

 Observer observer = new Observer() {
            @Override
            public void onSubscribe(Disposable d) {
//                d.dispose();
                Log.e("tag", "取消订阅 ");

            }

            @Override
            public void onNext(Object o) {
                Log.e("tag", "接收事件:" + o);
            }

            @Override
            public void onError(Throwable e) {

                Log.e("tag", " 数据处理出错");
            }

            @Override
            public void onComplete() {
                Log.e("tag", "数据处理完成");

            }
        };

 

 

最后用被观察者订阅观察者。

observable.subscribe(observer);

 

 

观察者与被观察者之间的关系:

观察者模式面向的需求是:A 对象(观察者)对 B 对象(被观察者)的某种变化高度敏感,需要在 B 变化的一瞬间做出反应。举个例子,新闻里喜闻乐见的警察抓小偷,警察需要在小偷伸手作案的时候实施抓捕。在这个例子里,警察是观察者,小偷是被观察者,警察需要时刻盯着小偷的一举一动,才能保证不会漏过任何瞬间。程序的观察者模式和这种真正的『观察』略有不同,观察者不需要时刻盯着被观察者(例如 A 不需要每过 2ms 就检查一次 B 的状态),而是采用注册(Register)或者称为订阅(Subscribe)的方式,告诉被观察者:我需要你的某某状态,你要在它变化的时候通知我。 Android 开发中一个比较典型的例子是点击监听器 OnClickListener 。对设置 OnClickListener 来说, View 是被观察者, OnClickListener 是观察者,二者通过 setOnClickListener() 方法达成订阅关系。订阅之后用户点击按钮的瞬间,Android Framework 就会将点击事件发送给已经注册的 OnClickListener 。采取这样被动的观察方式,既省去了反复检索状态的资源消耗,也能够得到最高的反馈速度。当然,这也得益于我们可以随意定制自己程序中的观察者和被观察者,而警察叔叔明显无法要求小偷『你在作案的时候务必通知我』。

 

 

1.2 just()

方法预览:

public static <T> Observable<T> just(T item)

......

public static <T> Observable<T> just(T item1, T item2, T item3, T item4, T item5, T item6, T item7, T item8, T item9, T item10)复制代码

有什么用?

创建一个被观察者,并发送事件,发送的事件不可以超过10个以上。


Observable.just(1, 2, 3)

.subscribe(new Observer < Integer > () {

    @Override

    public void onSubscribe(Disposable d) {

        Log.d(TAG, "=================onSubscribe");

    }

 

    @Override

    public void onNext(Integer integer) {

        Log.d(TAG, "=================onNext " + integer);

    }

 

    @Override

    public void onError(Throwable e) {

        Log.d(TAG, "=================onError ");

    }

 

    @Override

    public void onComplete() {

        Log.d(TAG, "=================onComplete ");

    }

});

 

1.3 From 操作符

1.3.1 fromArray()

方法预览:

public static <T> Observable<T> fromArray(T... items)复制代码

有什么用?

这个方法和 just() 类似,只不过 fromArray 可以传入多于10个的变量,并且可以传入一个数组。

怎么用?

Integer array[] = {1, 2, 3, 4};

Observable.fromArray(array)

.subscribe(new Observer < Integer > () {

    @Override

    public void onSubscribe(Disposable d) {

        Log.d(TAG, "=================onSubscribe");

    }

 

    @Override

    public void onNext(Integer integer) {

        Log.d(TAG, "=================onNext " + integer);

    }

 

    @Override

    public void onError(Throwable e) {

        Log.d(TAG, "=================onError ");

    }

 

    @Override

    public void onComplete() {

        Log.d(TAG, "=================onComplete ");

    }

});

 

1.3.2 fromCallable()

方法预览:

public static <T> Observable<T> fromCallable(Callable<? extends T> supplier)复制代码

有什么用?

这里的 Callable 是 java.util.concurrent 中的 Callable,Callable 和 Runnable 的用法基本一致,只是它会返回一个结果值,这个结果值就是发给观察者的。

怎么用?

Observable.fromCallable(new Callable < Integer > () {

 

    @Override

    public Integer call() throws Exception {

        return 1;

    }

})

.subscribe(new Consumer < Integer > () {

    @Override

    public void accept(Integer integer) throws Exception {

        Log.d(TAG, "================accept " + integer);

    }

});

 

 

1.3.3 fromFuture()

方法预览:

public static <T> Observable<T> fromFuture(Future<? extends T> future)复制代码

有什么用?

参数中的 Future 是 java.util.concurrent 中的 Future,Future 的作用是增加了 cancel() 等方法操作 Callable,它可以通过 get() 方法来获取 Callable 返回的值。

怎么用?


FutureTask < String > futureTask = new FutureTask < > (new Callable < String > () {

    @Override

    public String call() throws Exception {

        Log.d(TAG, "CallableDemo is Running");

        return "返回结果";

    }

});

 

Observable.fromFuture(futureTask)

    .doOnSubscribe(new Consumer < Disposable > () {

    @Override

    public void accept(Disposable disposable) throws Exception {

        futureTask.run();

    }

})

.subscribe(new Consumer < String > () {

    @Override

    public void accept(String s) throws Exception {

        Log.d(TAG, "================accept " + s);

    }

});

 

 

1.3.4 fromIterable()

方法预览:

public static <T> Observable<T> fromIterable(Iterable<? extends T> source)复制代码

有什么用?

直接发送一个 List 集合数据给观察者

怎么用?


List<Integer> list = new ArrayList<>();

list.add(0);

list.add(1);

list.add(2);

list.add(3);

Observable.fromIterable(list)

.subscribe(new Observer < Integer > () {

    @Override

    public void onSubscribe(Disposable d) {

        Log.d(TAG, "=================onSubscribe");

    }

 

    @Override

    public void onNext(Integer integer) {

        Log.d(TAG, "=================onNext " + integer);

    }

 

    @Override

    public void onError(Throwable e) {

        Log.d(TAG, "=================onError ");

    }

 

    @Override

    public void onComplete() {

        Log.d(TAG, "=================onComplete ");

    }

});

 

1.4 defer()

方法预览:

public static <T> Observable<T> defer(Callable<? extends ObservableSource<? extends T>> supplier)复制代码

有什么用?

这个方法的作用就是直到被观察者被订阅后才会创建被观察者。

怎么用?

// i 要定义为成员变量

Integer i = 100;

        

Observable<Integer> observable = Observable.defer(new Callable<ObservableSource<? extends Integer>>() {

    @Override

    public ObservableSource<? extends Integer> call() throws Exception {

        return Observable.just(i);

    }

});

 

i = 200;

 

Observer observer = new Observer<Integer>() {

    @Override

    public void onSubscribe(Disposable d) {

 

    }

 

    @Override

    public void onNext(Integer integer) {

        Log.d(TAG, "================onNext " + integer);

    }

 

    @Override

    public void onError(Throwable e) {

 

    }

 

    @Override

    public void onComplete() {

 

    }

};

 

observable.subscribe(observer);

 

i = 300;

 

observable.subscribe(observer);

 

 

运行结果:

05-20 20:05:01.443 26622-26622/? D/chan: ================onNext 200

================onNext 300

 

因为 defer() 只有观察者订阅的时候才会创建新的被观察者,所以每订阅一次就会打印一次,并且都是打印 i 最新的值

 

1.5 timer()

方法预览:

public static Observable<Long> timer(long delay, TimeUnit unit)

......复制代码

有什么用?

当到指定时间后就会发送一个 0L 的值给观察者。

怎么用?

Observable.timer(2, TimeUnit.SECONDS)

.subscribe(new Observer < Long > () {

    @Override

    public void onSubscribe(Disposable d) {

 

    }

 

    @Override

    public void onNext(Long aLong) {

        Log.d(TAG, "===============onNext " + aLong);

    }

 

    @Override

    public void onError(Throwable e) {

 

    }

 

    @Override

    public void onComplete() {

 

    }

});

 

打印结果:

05-20 20:27:48.004 27204-27259/com.example.louder.rxjavademo D/chan: ===============onNext 0

 

 

 

1.6 interval()

方法预览:

public static Observable<Long> interval(long period, TimeUnit unit)

public static Observable<Long> interval(long initialDelay, long period, TimeUnit unit)

......复制代码

有什么用?

每隔一段时间就会发送一个事件,这个事件是从0开始,不断增1的数字。

怎么用?

Observable.interval(4, TimeUnit.SECONDS)

.subscribe(new Observer < Long > () {

    @Override

    public void onSubscribe(Disposable d) {

        Log.d(TAG, "==============onSubscribe ");

    }

 

    @Override

    public void onNext(Long aLong) {

        Log.d(TAG, "==============onNext " + aLong);

    }

 

    @Override

    public void onError(Throwable e) {

 

    }

 

    @Override

    public void onComplete() {

 

    }

});

 

从时间就可以看出每隔4秒就会发出一次数字递增1的事件。这里说下 interval() 第三个方法的 initialDelay 参数,这个参数的意思就是 onSubscribe 回调之后,再次回调 onNext 的间隔时间。

 

 

 

 

 

 

1.7 intervalRange()

方法预览:

public static Observable<Long> intervalRange(long start, long count, long initialDelay, long period, TimeUnit unit)

public static Observable<Long> intervalRange(long start, long count, long initialDelay, long period, TimeUnit unit, Scheduler scheduler)复制代码

有什么用?

可以指定发送事件的开始值和数量,其他与 interval() 的功能一样。

怎么用?

Observable.intervalRange(2, 5, 2, 1, TimeUnit.SECONDS)

.subscribe(new Observer < Long > () {

    @Override

    public void onSubscribe(Disposable d) {

        Log.d(TAG, "==============onSubscribe ");

    }

 

    @Override

    public void onNext(Long aLong) {

        Log.d(TAG, "==============onNext " + aLong);

    }

 

    @Override

    public void onError(Throwable e) {

 

    }

 

    @Override

    public void onComplete() {

 

    }

});

打印结果:

05-21 00:03:01.672 2504-2504/com.example.louder.rxjavademo D/chan: ==============onSubscribe

05-21 00:03:03.674 2504-2537/com.example.louder.rxjavademo D/chan: ==============onNext 2

05-21 00:03:04.674 2504-2537/com.example.louder.rxjavademo D/chan: ==============onNext 3

05-21 00:03:05.674 2504-2537/com.example.louder.rxjavademo D/chan: ==============onNext 4

05-21 00:03:06.673 2504-2537/com.example.louder.rxjavademo D/chan: ==============onNext 5

05-21 00:03:07.674 2504-2537/com.example.louder.rxjavademo D/chan: ==============onNext 6

 

 

可以看出被观察者的事件产生,从2开始,总共发送5次,onSubscribe 回调

与onNext回调间隔时间为2秒,事件1秒发送一次。

 

 

1.8 range()

方法预览:

public static Observable<Integer> range(final int start, final int count)复制代码

有什么用?

同时发送一定范围的事件序列。

怎么用?

Observable.range(2, 5)

.subscribe(new Observer < Integer > () {

    @Override

    public void onSubscribe(Disposable d) {

        Log.d(TAG, "==============onSubscribe ");

    }

 

    @Override

    public void onNext(Integer aLong) {

        Log.d(TAG, "==============onNext " + aLong);

    }

 

    @Override

    public void onError(Throwable e) {

 

    }

 

    @Override

    public void onComplete() {

 

    }

});

打印结果:

05-21 00:09:17.202 2921-2921/? D/chan: ==============onSubscribe

==============onNext 2

==============onNext 3

==============onNext 4

==============onNext 5

==============onNext 6

 

 

1.9 rangeLong()

方法预览:

public static Observable<Long> rangeLong(long start, long count)复制代码

有什么用?

作用与 range() 一样,只是数据类型为 Long

 

1.10 empty() & never() & error()

方法预览:

public static <T> Observable<T> empty()

public static <T> Observable<T> never()

public static <T> Observable<T> error(final Throwable exception)复制代码

有什么用?

  1. empty() : 直接发送 onComplete() 事件
  2. never():不发送任何事件
  3. error():发送 onError() 事件


怎么用?

Observable.empty()

.subscribe(new Observer < Object > () {

 

    @Override

    public void onSubscribe(Disposable d) {

        Log.d(TAG, "==================onSubscribe");

    }

 

    @Override

    public void onNext(Object o) {

        Log.d(TAG, "==================onNext");

    }

 

    @Override

    public void onError(Throwable e) {

        Log.d(TAG, "==================onError " + e);

    }

 

    @Override

    public void onComplete() {

        Log.d(TAG, "==================onComplete");

    }

});

 

打印结果:

 

05-26 14:06:11.881 15798-15798/com.example.rxjavademo D/chan: ==================onSubscribe

==================onComplete

 

换成 never() 的打印结果:

05-26 14:12:17.554 16805-16805/com.example.rxjavademo D/chan: ==================onSubscribe

 

 

换成 error() 的打印结果:

05-26 14:12:58.483 17817-17817/com.example.rxjavademo D/chan: ==================onSubscribe

==================onError java.lang.NullPointerException

 

 

 

2. 转换操作符

2.1 map()

方法预览:

public final <R> Observable<R> map(Function<? super T, ? extends R> mapper)复制代码

有什么用?

map 可以将被观察者发送的数据类型转变成其他的类型

怎么用?

以下代码将 Integer 类型的数据转换成 String。

Observable.just(1, 2, 3)

.map(new Function < Integer, String > () {

    @Override

    public String apply(Integer integer) throws Exception {

        return "I'm " + integer;

    }

})

.subscribe(new Observer < String > () {

    @Override

    public void onSubscribe(Disposable d) {

        Log.e(TAG, "===================onSubscribe");

    }

 

    @Override

    public void onNext(String s) {

        Log.e(TAG, "===================onNext " + s);

    }

 

    @Override

    public void onError(Throwable e) {

 

    }

 

    @Override

    public void onComplete() {

 

    }

});

打印结果:

05-21 09:16:03.490 5700-5700/com.example.rxjavademo E/chan: ===================onSubscribe

===================onNext I'm 1

===================onNext I'm 2

===================onNext I'm 3

 

 

 

2.2 flatMap()

方法预览:

public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper)

......

有什么用?

这个方法可以将事件序列中的元素进行整合加工,返回一个新的被观察者。

怎么用?

flatMap() 其实与 map() 类似,但是 flatMap() 返回的是一个 Observerable。现在用一个例子来说明 flatMap() 的用法。

假设一个有一个 Person 类,这个类的定义如下:

public class Person {

 

    private String name;

    private List<Plan> planList = new ArrayList<>();

 

    public Person(String name, List<Plan> planList) {

        this.name = name;

        this.planList = planList;

    }

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

 

    public List<Plan> getPlanList() {

        return planList;

    }

 

    public void setPlanList(List<Plan> planList) {

        this.planList = planList;

    }

 

}

Person 类有一个 name 和 planList 两个变量,分别代表的是人名和计划清单。

Plan 类的定义如下:

 

 

 

public class Plan {

 

    private String time;

    private String content;

    private List<String> actionList = new ArrayList<>();

 

    public Plan(String time, String content) {

        this.time = time;

        this.content = content;

    }

 

    public String getTime() {

        return time;

    }

 

    public void setTime(String time) {

        this.time = time;

    }

 

    public String getContent() {

        return content;

    }

 

    public void setContent(String content) {

        this.content = content;

    }

 

    public List<String> getActionList() {

        return actionList;

    }

 

    public void setActionList(List<String> actionList) {

        this.actionList = actionList;

    }

}

现在有一个需求就是要将 Person 集合中的每个元素中的 Plan 的 action 打印出来。 首先用 map() 来实现这个需求看看:

 

Observable.fromIterable(personList)

.map(new Function < Person, List < Plan >> () {

    @Override

    public List < Plan > apply(Person person) throws Exception {

        return person.getPlanList();

    }

})

.subscribe(new Observer < List < Plan >> () {

    @Override

    public void onSubscribe(Disposable d) {

 

    }

 

    @Override

    public void onNext(List < Plan > plans) {

        for (Plan plan: plans) {

            List < String > planActionList = plan.getActionList();

            for (String action: planActionList) {

                Log.d(TAG, "==================action " + action);

            }

        }

    }

 

    @Override

    public void onError(Throwable e) {

 

    }

 

    @Override

    public void onComplete() {

 

    }

});

 

可以看到 onNext() 用了嵌套 for 循环来实现,如果代码逻辑复杂起来的话,可能需要多重循环才可以实现。

 

 

现在看下使用 flatMap() 实现:

 

Observable.fromIterable(personList)

.flatMap(new Function < Person, ObservableSource < Plan >> () {

    @Override

    public ObservableSource < Plan > apply(Person person) {

        return Observable.fromIterable(person.getPlanList());

    }

})

.flatMap(new Function < Plan, ObservableSource < String >> () {

    @Override

    public ObservableSource < String > apply(Plan plan) throws Exception {

        return Observable.fromIterable(plan.getActionList());

    }

})

.subscribe(new Observer < String > () {

    @Override

    public void onSubscribe(Disposable d) {

 

    }

 

    @Override

    public void onNext(String s) {

        Log.d(TAG, "==================action: " + s);

    }

 

    @Override

    public void onError(Throwable e) {

 

    }

 

    @Override

    public void onComplete() {

 

    }

});

 

 

从代码可以看出,只需要两个 flatMap() 就可以完成需求,并且代码逻辑非常清晰。

 

2.3 concatMap()

方法预览:

public final <R> Observable<R> concatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper)

public final <R> Observable<R> concatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper, int prefetch)复制代码

有什么用?

concatMap() 和 flatMap() 基本上是一样的,只不过 concatMap() 转发出来的事件是有序的,而 flatMap() 是无序的。

更多详情请看:

RxJava2 只看这一篇文章就够了 - 掘金

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值