RxJava是一个实现异步操作的库,采用链式掉用来实现响应式编程,使逻辑代码更加清晰。
RxJava类似观察者模式,Observables (被观察者)和 Observers(Subscribers) (观察者)通过 subscribe(订阅)方法实现订阅关系
Observables 在需要的时候发出事件来通知 Observers(Subscribers).
类似Android中Button的点击事件的监听:
Button -> 被观察者、OnClickListener -> 观察者、setOnClickListener() -> 订阅,onClick() -> 事件
和观察者模式不同的是 :
一个”热”的Observable可能一创建完就开始发射数据,因此所有后续订阅它的观察者可能从序列中间的某个位置开始接受数据(会丢失一些数据)。
一个”冷”的Observable会一直等待,直到有观察者订阅它才开始发射数据,因此这个观察者可以确保会收到整个数据序列。
RxJava中定义了三种回调方法:
创建一个RxJava掉用实现需要三个步骤
1. 创建观察者 Observer或者Subscriber
2. 创建被观察者 Observable
3. 订阅subscribe
HelloWorld:
@NonNull
private Observer<String> createObserver() {
return new Subscriber<String>() {
@Override
public void onNext(String s) {
Logger.d("Item: " + s);
}
@Override
public void onCompleted() {
Logger.d("Completed!");
}
@Override
public void onError(Throwable e) {
Logger.d("Error!");
}
};
}
@NonNull
private Observable<String> createObservable() {
return 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();
subscriber.onError(new Throwable());
}
});
}
这里传入了一个 OnSubscribe 对象作为参数.
OnSubscribe 会被存储在返回的 Observable 对象中,它的作用相当于一个计划表,
当 Observable 被订阅的时候,OnSubscribe 的 call() 方法会自动被调用,事件序列就会依照设定依次触发上面的定义就是:
观察者Subscriber 将会被调用三次 onNext() 和一次 onCompleted(),其中onError和onCompleted互斥。
被观察者调用了观察者的回调方法,就实现了由被观察者向观察者的事件传递,即观察者模式。
//Creating Observables
private void create() {
//1.观察者
Observer<String> subscriber = createObserver();
//2.被观察者
Observable<String> observable = createObservable();
//3.订阅
observable.subscribe(subscriber);
}
流式 API 的设计 使得 这里看起来像是:被观察者 订阅了 观察者
其中Subscriber是Observer的抽象类,在使用过程中,Observer 也总是会先被转换成一个 Subscriber 再使用
onStart():Subscriber类中新增方法,在subscribe所在线程执行,用于一些准备工作,如果需要指定线程可以使用doOnSubscribe()方法
unsubscribe():Subscriber类中新增方法,是Subscription接口中的方法,Subscriber实现它,用于取消订阅,可以放置内存泄漏
isUnsubscribed():Subscription接口中的方法,用于判断订阅状态,一般在使用unsubscribe()时先判断一下
just 和 from操作符用来快捷创建事件队列。
just(T...)
:将传入的参数依次发送出来(一次来将整个的数组发射出去)。
from(T[])/from(Iterable<? extends T>)
: 将传入的数组或 Iterable 拆分成具体对象后,依次发送出来(发射T.lenght次)。
from操作符可以转换Future、Iterable和数组,对于Iterable和数组,产生的Observable会发射Iterable或数组的每一项数据.
对于Future,它会发射Future.get()方法返回的单个数据
如果你传递null给Just,它会返回一个发射null值的Observable,如果需要空Observable你应该使用Empty操作符.
//1.观察者
Observer<String> subscriber = createObserver();
//2. 被观察者
//just
Observable observable = Observable.just("just", "test", "just");
上面代码将会依次调用:
onNext(“Hello”);
onNext(“Hi”);
onNext(“Aloha”);
onCompleted();或者程序出现异常掉用onError
//from
String[] words = {"from", "test", "from"};
Observable observable = Observable.from(words);
//3. 订阅
observable.subscribe(subscriber);
Range操作符发射一个范围内的有序整数序列,你可以指定范围的起始和长度。它接受两个参数,一个是范围的起始值,一个是范围的数据的数目。
如果你将第二个参数设为0,将导致Observable不发射任何数据(如果设置为负数,会抛异常)。
@NonNull
private Observer<Integer> createIntegerObserver() {
return new Subscriber<Integer>() {
@Override
public void onNext(Integer s) {
Logger.d("Item: " + s);
}
@Override
public void onCompleted() {
Logger.d("Completed!");
}
@Override
public void onError(Throwable e) {
Logger.d("Error!");
}
};
}
private void range() {
//1.观察者
Observer<Integer> subscriber = createIntegerObserver();
//2.被观察者
Observable observable = Observable.range(10, 5);
//3:订阅:
observable.subscribe(subscriber);
}
上述代码将会打印10、11、12、13、14、Completed!
Defer操作符只有当有Subscriber来订阅的时候才会创建一个新的Observable对象,
每次订阅都会得到一个刚创建的最新的Observable对象,确保Observable对象里的数据是最新的.
Defer操作符会一直等待直到有观察者订阅它,然后它使用Observable工厂方法生成一个Observable。
如下代码就会打印当前实时时间
private void defer() {
Observable.defer(new Func0<Observable<String>>() {
@Override
public Observable<String> call() {
return Observable.just(System.currentTimeMillis() + "");
}
})
.subscribe(createStringObserver());
}
和 just不同的是,just可以将数字、字符串、数组、Iterate对象转为Observable对象发射出去,但值是创建的时候就不变了的。
Action是RxJava中专门用于处理 (无返回值) 的不完整回调的,RxJava 会自动根据定义创建出 Subscriber 。
相当于一个包装对象,比如Action0是无参无返回值的 ,只有一个方法 call(),常用于包装onCompleted(),
Action1带一个参数,只有一个方法 call(T param),常用于包装onNext(obj) 和 onError(error),
RxJava 提供了多个 ActionX 形式的接口 (例如 Action2, Action3)
private void action() {
//1.观察者
Action1<String> onNextAction = new Action1<String>() {
// onNext()
@Override
public void call(String s) {
Logger.d(s);
}
};
Action1<Throwable> onErrorAction = new Action1<Throwable>() {
// onError()
@Override
public void call(Throwable throwable) {
// Error handling
Logger.d(throwable.toString());
}
};
Action0 onCompletedAction = new Action0() {
// onCompleted()
@Override
public void call() {
Logger.d("completed");
}
};
//2.被观察者
rx.Observable<String> observable = Observable.just("just", "just", "just", "just");
//3.订阅
// 自动创建 Subscriber ,并使用 onNextAction、 onErrorAction 和 onCompletedAction 来定义 onNext()、 onError() 和 onCompleted()
observable.subscribe(onNextAction, onErrorAction, onCompletedAction);
}
subscribe相关源码
public final Subscription subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError, final Action0 onComplete) {
if (onNext == null) {
throw new IllegalArgumentException("onNext can not be null");
}
if (onError == null) {
throw new IllegalArgumentException("onError can not be null");
}
if (onComplete == null) {
throw new IllegalArgumentException("onComplete can not be null");
}
return subscribe(new Subscriber<T>() {
@Override
public final void onCompleted() {
onComplete.call();
}
@Override
public final void onError(Throwable e) {
onError.call(e);
}
@Override
public final void onNext(T args) {
onNext.call(args);
}
});
}
如果只关心onNext(),即之上的deffer实例可以写成如下形式
Observable.defer(() -> Observable.just(System.currentTimeMillis() + "")).subscribe(s -> Logger.d(s));
在不指定线程的情况下, RxJava 遵循的是线程不变的原则,
即:在哪个线程调用 subscribe(),就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。如果需要切换线程,就需要用到 Scheduler (调度器)。
RxJava内置Scheduler,Schedulers.from(executor): 使用指定的Executor作为调度器
注意:
Scheduler实例:
private void scheduler() {
int drawableRes = R.mipmap.ic_launcher;
ImageView imageView = new ImageView(this);
Observable.create(new Observable.OnSubscribe<Drawable>() {
@Override
public void call(Subscriber<? super Drawable> subscriber) {
Drawable drawable = getResources().getDrawable(drawableRes);
subscriber.onNext(drawable);
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
.subscribe(new Observer<Drawable>() {
@Override
public void onNext(Drawable drawable) {
imageView.setImageDrawable(drawable);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Logger.d("Error!");
}
});
}
Interval所创建的Observable对象会从0开始,每隔固定的时间发射一个整数。需要注意的是这个对象是运行在computation Scheduler, 如果涉及到UI操作,需要切换到主线程执行
它按固定的时间间隔发射一个无限递增的整数序列
实例:
private void interval() {
Observable.interval(1, TimeUnit.SECONDS).
observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Long>() {
@Override
public void onCompleted() {
Logger.d("onCompleted");
}
@Override
public void onError(Throwable e) {
Logger.d("onError" + e.getMessage());
}
@Override
public void onNext(Long aLong) {
Logger.d("interval:" + aLong);
}
});
}
打印结果:interval:0,interval:1,interval:2…
Repeat会将一个Observable对象重复发射,我们可以指定其发射的次数,当 .repeat() 接收到 .onCompleted() 事件后触发重订阅。
实例:
private void repeat() {
Observable.just(1, 2, 3, 4, 5).repeat(5).observeOn(AndroidSchedulers.mainThread()).subscribe(integer -> Logger.d(integer + ""));
}
打印结果:会重复打印5次 1,2,3,4,5
Timer会在指定时间后发射一个,注意其也是运行在computation Scheduler
private void timer() {
Observable.timer(3, TimeUnit.SECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(l -> Logger.d(l + ""));
}
延迟3秒之后会在logcat打印一个0
public void error() {
Observable.error(new Throwable("error!")).
observeOn(AndroidSchedulers.mainThread(), true).
subscribe(this::logger);
}
— 创建一个重复发射指定数据或数据序列的Observable,它依赖于另一个Observable发射的数据.字面意思就是什么时候重新订阅。
public void repeatWhen() {
Observable.range(10, 5).
repeatWhen(new Func1<Observable<? extends Void>, Observable<?>>() {
@Override
public Observable<?> call(Observable<? extends Void> observable) {
return Observable.timer(3, TimeUnit.SECONDS);
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
logger(integer);
}
});
}
会在第一遍数据发射完成后,延迟3秒重订阅一次(只重新订阅一次)。
打印结果:
10,11,12,13,14 –>隔3秒
10,11,12,13,14
而如下代码实现了延迟重复轮询订阅
Observable.range(10, 5).
repeatWhen(new Func1<Observable<? extends Void>, Observable<?>>() {
@Override
public Observable<?> call(Observable<? extends Void> observable) {
return observable.delay(2, TimeUnit.SECONDS);
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
logger(integer);
}
});
打印结果:
10,11,12,13,14 –>隔2秒
10,11,12,13,14 –>隔2秒
……….
示例代码:Creating.java
参考:
ReactiveX文档中文翻译
给 Android 开发者的 RxJava 详解
RxJava操作符(一)Creating Observables