Rxjava学习
Rxjava是jvm实现的响应式扩展,是一个基于观察者模式和处理异步的一个项目。
Rxjava1.0
准备
//rxjava的包
compile 'io.reactivex:rxjava:1.0.14'
//android线程的包
compile 'io.reactivex:rxandroid:1.0.1'
观察者模式
observer(观察者)通过观察Observable(被观察者)的行为,做出反应,可以有多个观察者来订阅Observable。如,按下开关,灯亮。灯就是一个observer观察者,开关是一个observable被观察者,也就是目标,按下开关,灯做出反应。
observer
public interface Observer {
void close();
}
Observable
public interface Observable {
void add(Observer observer);
void remove(Observer observer);
void closeLight();
}
light
public class Light implements Observer {
private String name;
public Light(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void close() {
// observable.closeLight();
System.out.println(name+"关闭了!");
}
}
Switch
public class Switch implements Observable {
/**
* 维护一个,观察者灯的集合
*/
List<Observer> list = new ArrayList<>();
@Override
public void closeLight() {
for (Observer light : list) {
//关灯
light.close();
}
}
@Override
public void remove(Observer observer) {
list.remove(observer);
}
@Override
public void add(Observer observer) {
list.add(observer);
}
}
Test
public class Test {
public static void main(String[] args) {
/**
* 创造灯对象
*/
Light light1 = new Light("灯1");
Light light2 = new Light("灯2");
Light light3 = new Light("灯3");
Light light4 = new Light("灯4");
Light light5 = new Light("灯5");
/**
* 被观察者Observable
*/
Switch swith = new Switch();
swith.add(light1);
swith.add(light2);
swith.add(light3);
swith.add(light4);
swith.add(light5);
//关灯
swith.closeLight();
}
}
输出
灯1关闭了!
灯2关闭了!
灯3关闭了!
灯4关闭了!
灯5关闭了!
基本用法
基本用法1:只有调用subscribe时,事件才发送,并且在call方法中,由于Subscriber中有onStart方法,就是在订阅时,用来进行初始化。
subscriber返回subscription对象,可以调用isUnsubscribed进行判断时候解绑,再根据判断选择调用
UnSubcribe()方法解绑。如果不解绑Observable会一直持有observer的引用,容易造成OOM。
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("1");
subscriber.onNext("2");
// subscriber.onError(new Throwable("我是exception"));
subscriber.onNext("3");
subscriber.onNext("4");
subscriber.onCompleted();
}
}).subscribe(new Observer<String>() {
@Override
public void onCompleted() {
System.out.println("事件完毕");
}
@Override
public void onError(Throwable e) {
System.out.println("exception come out ");
}
@Override
public void onNext(String s) {
System.out.println(s);
}
});
- 基本用法2:just内部也是调用onNext,在调用onCompeleted
Observable.just("1","2","3","4").subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println("事件完毕");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
System.out.println(s);
}
});
- 基本用法3:支持数据,集合
String[] s = {"1","2","3","4"};
Observable.from(s).subscribe(new Subscriber<String>() {
@Override
public void onStart() {
super.onStart();
System.out.println("i start 了 start 数据 清零重置");
}
@Override
public void onCompleted() {
System.out.println("事件完毕");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
System.out.println(s);
}
});
- 基本用法4:不完全调用,Action-onCompeleted,
Action1-onError,Action1-onNext,
subscribe绑定是,内部调用。
/**
* 不完全调用,action
*/
Action1<String> action1 = new Action1<String>() {
@Override
public void call(String s) {
System.out.println(s);
}
};
Action1<Throwable> error = new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
System.out.println(throwable.toString());
}
} ;
Action0 compeleted = new Action0() {
@Override
public void call() {
System.out.println("事件发送完毕了,我是action");
}
};
/**
* subscribe(action,,);原理接口回调,内部实例化一个Subscriber对象,在onnext,onerror,oncompeleted
* 处调用相应的action.call;
*/
Observable.just("1","2","3","4").subscribe(action1,error,compeleted);
rxjava的线程调度(scheduler)
rxjava是用来处理异步的,前面只是同步操作,异步操作需要进行线程的操作。
- scheduler.immediate(),当前线程。
- scheduler.newThread(),新开一个线程。
- scheduler.io(),io线程,进行数据库读取,网络等操作
- scheduler.computation(),线程计算
- AndroidScheduler.mainThread(),android特有的主线程
- subscribeOn()方法,返回的Observable对象在OnSubscribe的时候切换线程,通知old Observable发送subscriber它指示Observable在一个指定的调度器上创建(只作用于被观察者创建阶段)。只能指定一次,如果指定多次则以第一次为准.
- observerOn()方法,返回的Observable对象在其new Observable的subscriber对象中切换线程,可以频繁的切换线程。
- 在subscribe()方法调用时,其中的onStart()会先被调用,但是不能指定线程,而是只能执行在 subscribe() 被调用时的线程。
- Observable.doOnSubscribe(),默认也是在subscribe()调用时的线程,在执行到subscribe()方法是时调用,但是如果此方法后面有subscribeOn()方法,则会在此指定的线程中调用。
class mapFunc implements Func1<String, Integer> {
@Override
public Integer call(String s) {
return Integer.parseInt(s);
}
}
class doAction implements Action0 {
@Override
public void call() {
//here initialization
}
}
class subAction1 implements Action1<String> {
@Override
public void call(String s) {
System.out.println(s);
}
}
Observable.just("2") //ui线程,new 通知 old Observable 在onSubscribe切换
.doOnSubscribe(new doAction()) //指定在ui线程中初始化
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.newThread()) //在new 通知 old Observable 在新的Observable中切换
// .map(new mapFunc())
.subscribe(new subAction1()); //新线程
rxjava中的变换
- map,一对一变换,String->Integer
/* Observable.just("1","2","3")
.map(new Func1<String, Integer>() {
@Override
public Integer call(String s) {
return Integer.parseInt(s);
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println(integer);
}
});*/
- flatmap,一对多变换,student->observable
Observable.create(new Observable.OnSubscribe<Student>() {
@Override
public void call(Subscriber<? super Student> subscriber) {
subscriber.onNext(new Student("bob", list));
}
}).flatMap(new Func1<Student, Observable<Course>>() {
@Override
public Observable<Course> call(Student student) {
//将数据重新生成observable对象,将老的subscriber替换为新的,一条条数据发送
return Observable.from(student.getCourseInstance());
}
}).subscribe(new Action1<Course>() {
@Override
public void call(Course course) {
int grades = course.getGrades();
System.out.println("flatMap转换的数据:"+grades);
}
});
- compose,observable自身变换
/**
* 自身变换Observable
*
*/
//compose方法
public <R> Observable<R> compose (Transformer < ? super T,?extends R > transformer){
return ((Transformer<T, R>) transformer).call(this);
}
// Transformer接口
public interface Transformer<T, R> extends Func1<Observable<T>, Observable<R>> {
// cover for generics insanity
}
class transformerMyObservable implements Observable.Transformer<String, Integer> {
@Override
public Observable<Integer> call(Observable<String> stringObservable) {
return stringObservable.lift()
.lift()
.lift();
}
}
Observable.just("1").compose(new transformerMyObservable()).subscribe();
Observable.just("w").compose(new transformerMyObservable()).subscribe();
Observable.just("e").compose(new transformerMyObservable()).subscribe();
Observable.just("t").compose(new transformerMyObservable()).subscribe();
backpressure
是一种在异步环境下的一种策略,通过下数据流告诉上数据流,要发送多少数据的策略。
问题:如果在异步中,Observable发送数据的速度大于observer处理的速度,则数据就会堆积,在rxjava
1.0时,会出现MissingBackpressureException,而在rxjava2.0中则不会出现异常,知道数据堆积过多,没有及时处理知道出现OOM内存溢出。怎么办?backpressure就是为了解决这个问题的。
interval,一ms,发送一次,处理时是1s处理一个,造成异常出现。
/**
* 在Rxjava1.0时,
* 1.Hot Observable(只要创建observable,就会发送数据)如interval,不支持backpressure
* onBackpressureBuffer():将数据缓存,调用request()时,发数据。
* onBackpressureDrop():只有在subscribe方法中调用request()时,才会发送数据,其他时间清除数据
* 2.cool Observable(只有在subscribe的时候,才会发送),平时基本使用,支持backpressures
*
* 在Rxjava2.0时,就是为了解决backpressure的问题
*/
// Caused by: rx.exceptions.MissingBackpressureException
Observable.interval(1, TimeUnit.MILLISECONDS)
// .just("2")
.observeOn(Schedulers.newThread())
.subscribe(new Action1<Long>() {
@Override
public void call(Long s) {
try {
Thread.sleep(1000);
System.out.println(s++);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Rxjava2.0
rxjava2.0进行了一次大改,对backpressure有了明确的划分,删除了和添加了一些方法。官网:https://github.com/ReactiveX/RxJava/wiki/What’s-different-in-2.0
准备
compile 'io.reactivex.rxjava2:rxjava:2.0.3'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
不允许传递null
在2.0中不能够传递null值了,否则会报++NullPointerException++
Observable.just(null);
Observable 和 flowable
observable 和 flowable 都有两套不一样的方法。
- Observable变成了abstract类,父类为ObservableSource(interface) ,不支持backpressure。
- Observer观察者,内部有四个方法,onNext,onError,onCompelet,onSubscribe(Disposable d)。
- onSubscribe相当于初始化onStart,disposable对象,可以再内部进行取消订阅。
- 官方建议发送事件不超过1000时,使用observable
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("1");
e.onNext("2");
e.onNext("3");
e.onNext("4");
e.onComplete();
}
}).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
//onstart,取消订阅
mTextView.append("开始");
// d.dispose(); 取消订阅
}
@Override
public void onNext(String s) {
mTextView.append(s + ".....next");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
mTextView.append("completed");
}
});
- Flowable (abstract),父类Publisher(interface),支持backpressure。
- subscriber观察者,内部有四个方法,onNext,onError,onCompelet,onSubscribe(Subscription s)。
- onSubscribe初始化,subscription对象,含有连个方法request(向上流发出请求)和cancel(取消订阅),request时,会直接执行onNext不会执行后面的内容,所以必须在request前面初始化完成。
- 使用create创造flowable对象时需要制定backpressure类型,5种。
Flowable.create(new FlowableOnSubscribe<String>() {
@Override
public void subscribe(FlowableEmitter<String> e) throws Exception {
e.onNext("1");
e.onNext("2");
e.onNext("3");
e.onNext("4");
e.onNext("5");
e.onNext("6");
e.onComplete();
}
}, BackpressureStrategy.BUFFER)
.subscribe(new Subscriber<String>() {
@Override
public void onSubscribe(Subscription s) {
//初始化
mTextView.append("\r\nonSubscribe start");
s.request(Long.MAX_VALUE);//不使用backpressure
mTextView.append("\r\nonSubscribe end");
}
@Override
public void onNext(String s) {
mTextView.append("\r\nonNext :" + s);
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
mTextView.append("\r\nonComplete");
}
});
- subscription和disposable接口
* public interface Subscription { public interface Disposable {
* public void request(long n); (支持backpressure) void dispose();
* public void cancel(); (取消订阅) boolean isDisposed();
* } }
- BackpressureStrategy
/**
* Represents the options for applying backpressure to a source sequence.
*/
public enum BackpressureStrategy {
/**
* OnNext events are written without any buffering or dropping.
* Downstream has to deal with any overflow.
* <p>Useful when one applies one of the custom-parameter onBackpressureXXX operators.
*/
MISSING,
/**
* Signals a MissingBackpressureException in case the downstream can't keep up.
*/
ERROR,
/**
* Buffers <em>all</em> onNext values until the downstream consumes it.
*/
BUFFER,
/**
* Drops the most recent onNext value if the downstream can't keep up.
*/
DROP,
/**
* Keeps only the latest onNext value, overwriting any previous value if the
* downstream can't keep up.
*/
LATEST
}
Action 和function
- 在Rxjava2.0中 action0 -> action ,action1 ->Consumer , action2 ->BiConsumer,其他的被移除
- Function -> Function , Function2 -> BiFunction,其他依然存在
- from—> fromArray,from…,并且不是数组里的一个个发送而是发送整个数组。
/**
* 不完全调用action0->action , action1 ->Consumer , action2 ->BiConsumer
* Function -> Function , Function2 -> BiFunction
*
* fromArray(T[] t) 是一次性发送一个数组 在ObservableFromArray中重写了方法subscribeActual
*/
Consumer<int[]> onNext = new Consumer<int[]>() {
@Override
public void accept(int[] integer) throws Exception {
mTextView.append("**"+ Arrays.toString(integer)+"**");
}
};
Consumer<Throwable> onError = new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
mTextView.append("**"+throwable.toString()+"**");
}
};
Consumer<Disposable> onSubscribe = new Consumer<Disposable>() {
@Override
public void accept(Disposable disposable) throws Exception {
mTextView.append("**"+disposable.isDisposed()+"**");
}
};
final Action onCompeleted = new Action() {
@Override
public void run() throws Exception {
mTextView.append("**onCompeleted 调用了**");
}
};
int[] s = {1,2,3,4};
Observable.fromArray(s)
.subscribe(onNext,onError,onCompeleted,onSubscribe);
subScribe()绑定
/**
* subscribe(Observer&&Subscriber) 订阅方法的参数为observer或者subscriber时返回为void,1.0为subscription
* 而subscribe(Consumer) 参数为Consumer时,返回的是Disposable对象,用来dispose取消订阅事件,避免OOM
* 而Observer,Subscriber参数里面onSubscribe(Disposable&&Subscription) 可以内部取消订阅
* 想要外部取消,需要使用subscribeWith()返回的是Subscriber或者observer对象,
*
* 所以要使用Observer的子类ResourceObserver(也实现了Disposable),Subscriber的子类ResourceSubscriber(也实现了Disposable)
*
* 然后使用 CompsiteDispoasble.add(),subscriberWith返回的值,进行统一取消订阅。
*/
2.0中的doOnCancel/doOnDispose/unsubscribeOn
- 并不会取消,除非后面有真正取消事件如onCancel,dispose.
Flowable.just(1, 2, 3)
.doOnCancel(() -> System.out.println("Cancelled!"))
.subscribe(System.out::println);
- 会执行Cancelled
- take为新的操作符,使用take(n)操作符,会在onNext执行n个事件后,取消。
Flowable.just(1, 2, 3)
.doOnCancel(() -> System.out.println("Cancelled!"))
.take(2)
.subscribe(System.out::println);