RxJava

来源:互联网 发布:seo.chinaz 编辑:程序博客网 时间:2024/04/28 14:18

小米笔记本还是没见到高配版,So disapp

Rxjava是什么鬼?

“a library for composing asynchronous and event-based programs using observable sequences for the Java VM”
(翻译)一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库

流式API—观察者模式

这里写图片描述

Rxjava的观察者模式:

RxJava 有四个基本概念

  1. Observable (可观察者,即被观察者)
  2. Observer (观察者)
  3. subscribe (订阅)
  4. 事件

ObservableObserver 通过 subscribe() 方法实现订阅关系,从而 Observable 可以在需要的时候发出事件来通知 Observer

Rxjava的事件回调:

除了普通事件 onNext() (相当于 onClick() / onEvent())之外,还定义了两个特殊的事件:onCompleted() 和 onError()。

  1. onCompleted(): 事件队列完结。RxJava 不仅把每个事件单独处理,还会把它们看做一个队列。RxJava 规定,当不会再有新的 onNext() 发出时,需要触发 onCompleted() 方法作为标志
  2. onError(): 事件队列异常。在事件处理过程中出异常时,onError() 会被触发,同时队列自动终止,不允许再有事件发出。
  3. 在一个正确运行的事件序列中, onCompleted() 和 onError() 有且只有一个,并且是事件序列中的最后一个。需要注意的是,onCompleted() 和 onError() 二者也是互斥的,即在队列中调用了其中一个,就不应该再调用另一个。

    总体图:

创建Observer(观察者)

Observer<String> observer = new Observer<String>() {    @Override    public void onNext(String s) {        Log.d(tag, "Item: " + s);    }    @Override    public void onCompleted() {        Log.d(tag, "Completed!");    }    @Override    public void onError(Throwable e) {        Log.d(tag, "Error!");    }};

RxJava 还内置了一个实现了 Observer 的抽象类:Subscriber

创建方式:

Subscriber<String> subscriber = new Subscriber<String>() {    @Override    public void onNext(String s) {        Log.d(tag, "Item: " + s);    }    @Override    public void onCompleted() {        Log.d(tag, "Completed!");    }    @Override    public void onError(Throwable e) {        Log.d(tag, "Error!");    }};

Subscriber 和 Observer 的区别

事实上,在 RxJava 的 subscribe 过程中,Observer 也总是会先被转换成一个 Subscriber 再使用

  1. onStart(): 这是 Subscriber 增加的方法。

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

  2. unsubscribe(): 这是 Subscriber 所实现的另一个接口 Subscription 的方法,用于取消订阅。

    在这个方法被调用后,Subscriber 将不再接收事件。一般在这个方法调用前,可以使用 isUnsubscribed() 先判断一下状态。 unsubscribe() 这个方法很重要,因为在 subscribe() 之后, Observable 会持有 Subscriber 的引用,这个引用如果不能及时被释放,将有内存泄露的风险。所以最好保持一个原则:要在不再使用的时候尽快在合适的地方(例如 onPause() onStop() 等方法中)调用 unsubscribe() 来解除引用关系,以避免内存泄露的发生。

创建Observable(被观察者)

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

当 Observable 被订阅的时候,OnSubscribe 的 call() 方法会自动被调用,事件序列就会依照设定依次触发(对于上面的代码,就是观察者Subscriber 将会被调用三次 onNext() 和一次 onCompleted())。这样,由被观察者调用了观察者的回调方法,就实现了由被观察者向观察者的事件传递,即观察者模式。

好,到目前未知已经看到了两个在订阅的时候主动调用的函数:Subscriber 的onStart()以及Observable 的OnSubscribe call( ) 方法

Subscribe (订阅)

创建了 Observable 和 Observer 之后,再用 subscribe() 方法将它们联结起来

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

Observable.subscribe(Subscriber) 的内部实现是这样的(仅核心代码):

// 注意:这不是 subscribe() 的源码,而是将源码中与性能、兼容性、扩展性有关的代码剔除后的核心代码。// 如果需要看源码,可以去 RxJava 的 GitHub 仓库下载。public Subscription subscribe(Subscriber subscriber) {    subscriber.onStart();    onSubscribe.call(subscriber);    return subscriber;}

答案就在这:

  1. 调用 Subscriber.onStart() 。
  2. 调用 Observable 中的 OnSubscribe.call(Subscriber) 。
  3. 将传入的 Subscriber 作为 Subscription 返回。这是为了方便 unsubscribe().

所以,Observable 是什么时候发送事件的?

上面解释的很清楚:
在它被订阅的时候,即当 subscribe() 方法执行的时候,不是在创建的时候就立即开始发送事件

Action0 和Action1

Action0 的call()无参数无返回

Action0 onCompletedAction = new Action0() {    // onCompleted()    @Override    public void call() {        Log.d(tag, "completed");    }};

Action1 call(T t)有参数无返回

Action1<String> onNextAction = new Action1<String>() {    // onNext()    @Override    public void call(String s) {        Log.d(tag, s);    }};

所以

  1. 由于 onCompleted() 方法也是无参无返回值的,因此 Action0 可以被当成一个包装对象,将 onCompleted() 的内容打包起来将自己作为一个参数传入 subscribe() 以实现不完整定义的回调。
  2. 由于 onNext(T obj)onError(Throwable error) 也是单参数无返回值的,因此 Action1 可以将 onNext(obj) 和 onError(error) 打包起来传入 subscribe() 以实现不完整定义的回调。
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);

线程控制 —— Scheduler (一)

Scheduler 的 API

  • Schedulers.immediate(): 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。
  • Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。
  • Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
  • Schedulers.computation(): 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
  • Android 还有一个专用的 AndroidSchedulers.mainThread(),它指定的操作将在 Android 主线程运行。

subscribeOn():

指定 subscribe() 所发生的线程,即 Observable.OnSubscribe 被激活时所处的线程

observeOn():

指定 Subscriber 所运行在的线程

变换:

先介绍Func1

Func1 的类。它和 Action1 非常相似
但是Func1 包装的是有返回值的方法

new Func1<String, Bitmap>() {        @Override        public Bitmap call(String filePath) { // 参数类型 String            return getBitmapFromPath(filePath); // 返回类型 Bitmap        }

未完待续。。。下节讲变换符

参考:
http://gank.io/post/560e15be2dca930e00da1083

0 0