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 Observable create(ObservableOnSubscribe 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 Observable just(T item)

......

public static Observable 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 Observable 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 Observable fromCallable(Callable 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 Observable fromFuture(Future 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 Observable fromIterable(Iterable source)复制代码

有什么用?

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

怎么用?


List 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 Observable defer(Callable> supplier)复制代码

有什么用?

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

怎么用?

// i 要定义为成员变量

Integer i = 100;

        

Observable observable = Observable.defer(new Callable>() {

    @Override

    public ObservableSource call() throws Exception {

        return Observable.just(i);

    }

});

 

i = 200;

 

Observer observer = new Observer() {

    @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 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 interval(long period, TimeUnit unit)

public static Observable 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 intervalRange(long start, long count, long initialDelay, long period, TimeUnit unit)

public static Observable 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 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 rangeLong(long start, long count)复制代码

有什么用?

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

 

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

方法预览:

public static Observable empty()

public static Observable never()

public static Observable 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 Observable map(Function 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 Observable flatMap(Function> mapper)

......

有什么用?

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

怎么用?

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

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

public class Person {

 

    private String name;

    private List planList = new ArrayList<>();

 

    public Person(String name, List planList) {

        this.name = name;

        this.planList = planList;

    }

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

 

    public List getPlanList() {

        return planList;

    }

 

    public void setPlanList(List planList) {

        this.planList = planList;

    }

 

}

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

Plan 类的定义如下:

 

 

 

public class Plan {

 

    private String time;

    private String content;

    private List 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 getActionList() {

        return actionList;

    }

 

    public void setActionList(List 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 Observable concatMap(Function> mapper)

public final Observable concatMap(Function> mapper, int prefetch)复制代码

有什么用?

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

更多详情请看:

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

你可能感兴趣的:(Android,框架)