android rxjava 2.x 框架性学习

来源:互联网 发布:软件开发的学校 编辑:程序博客网 时间:2024/05/03 09:56

android rxjava 2.x 框架性学习

RxJava
是一个Java虚拟机实现的有效扩展框架:用于通过使用观察序列构成异步和基于事件编程的程序库
它扩展了观察者模式,以支持数据/事件序列,通过增加操作符,将序列清晰的组合在一起的。
这些序列组合可以是抽象出来的某些数据/事件,如低级别的线程,同步,线程安全和并发数据结构。
它是一种响应式编程库。

RxJava实现策略:
通过扩展的观察者模式,异步实现(不同线程间)Observable的事件序列的发送,Observer接收、处理事件
事件序列:
可以是诸如网络访问、数据库操作、文件读取、按键、List遍历等事件类型

RxJava框架核心:
1、扩展的观察者模式
Observable/Flowable(支持Backpressure背压,Backpressure策略仅是处理Subscriber接收事件的方式,2.x中添加Flowable支持背压,Observable设计成非背压) (被观察者)
Observer/Subscriber (观察者)
subscribe (订阅)
event(事件)
Observable和Observer通过 subscribe()方法实现订阅关系,Observable可以在需要的时候发出事件来通知 Observer

常用观察者模式:
Observable/Observer
Flowable/Subscriber
Single/SingleObserver
Completable/CompletableObserver
Maybe/MaybeObserver

观察者:
Observer、Subscriber、SingleObserver、MaybeObserver、CompletableObserver

public interface Observer<T> {    void onSubscribe(Disposable d);    void onNext(T t);    void onError(Throwable e);    void onComplete();}public interface Subscriber<T> {    public void onSubscribe(Subscription s);    public void onNext(T t);    public void onError(Throwable t);    public void onComplete();}interface SingleObserver<T> { //遵循协议 onSubscribe (onSuccess | onError)    void onSubscribe(Disposable d);    void onSuccess(T value);    void onError(Throwable error);}public interface MaybeObserver<T> { //遵循协议:onSubscribe(onSuccess | onError | onComplete)    void onSubscribe(Disposable d);    void onSuccess(T t);    void onError(Throwable e);    void onComplete();}public interface CompletableObserver { //遵循协议 onSubscribe (onComplete | onError)    void onSubscribe(Disposable d);    void onComplete();    void onError(Throwable e);}DefaultSubscriber:public abstract class DefaultSubscriber<T> implements FlowableSubscriber<T>//通过实现Subscriber接口,可以通过调用request(long n)方法请求或者cancel()方法取消订阅(同步请求)DisposableSubscriberpublic abstract class DisposableSubscriber<T> implements FlowableSubscriber<T>, Disposable//通过实现Desposable异步删除。ResourceSubscriberpublic abstract class ResourceSubscriber<T> implements FlowableSubscriber<T>, Disposable //允许异步取消其订阅相关资源,节省内存而且是线程安全。SafeSubscriberpublic final class SafeSubscriber<T> implements FlowableSubscriber<T>, Subscription//包装另一个订阅者,并确保所有onXXX方法遵守协议(序列化要求访问除外)。SerializedSubscriberpublic final class SerializedSubscriber<T> implements Subscriber<T>, Subscription//序列化访问另一个订阅者的onNext,onErroronComplete方法。

Observable创建方式:
1、

Observable.create()方式:Observable<Integer>  observable = Observable.create(new ObservableOnSubscribe<Integer>() {    @Override    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {        emitter.onNext(1);        ...        emitter.onComplete();    }});//java1.8 语法形式Observable<Object> source = Observable.create((ObservableEmitter<Object> emitter) -> {    emitter.onNext(1);    ...    emitter.onComplete();});source.subscribe(e -> { /* Ignored. */ }, Throwable::printStackTrace);Flowable<Integer> flowable = Flowable.create(new FlowableOnSubscribe<Integer>() {     @Override     public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {         emitter.onNext(1);         ...         emitter.onComplete();     }}, BackpressureStrategy.ERROR);

2、
just()方式

Observable<String> observable = Observable.just("Hello");

使用just()创建一个Observable并自动为调用onNext()发射数据。just()中传递的参数将直接在Observer的onNext()方法中接收到
3、

fromIterable()方式(fromArray,fromIterable,fromFuture):List<String> list = new ArrayList<String>();for(int i =0;i<10;i++){   list.add("number "+i);}Observable<String> observable = Observable.fromIterable((Iterable<String>) list);//fromIterable()遍历集合,发送每个item,每个item对应一次onNext()方法调用。List<Integer> list = new ArrayList<>();list.add(1);list.add(1);list.add(5);Flowable.fromIterable(list)        .subscribe(num -> System.out.println(num));Flowable.fromArray(1, 0, 6)        .filter(new Predicate<Integer>() {            @Override            public boolean test(Integer integer) throws Exception {                return integer.intValue() > 5;            }        })        .subscribe(new Consumer<Integer>() {            @Override            public void accept(Integer integer) throws Exception {                System.out.println(integer);            }        });    

注意:
Collection接口是Iterable接口的子接口,所以所有Collection接口的实现类都可以作为Iterable对象直接传入fromIterable()方法
4、
defer()方式

Observable<String> observable = Observable.defer(new Callable<ObservableSource<? extends String>>() {    @Override    public ObservableSource<? extends String> call() throws Exception {           return Observable.just("hello");    }});

订阅时创建Observable,针对每个观察者创建一个新的Observable。
5、
interval()方式

Observable<Integer> observable = Observable.interval(1, TimeUnit.SECONDS);

创建一个按固定时间间隔发射整数序列的Observable,按间隔时间调用onNext()方法(持续进行)。
6、
range()方式

Observable<Integer> observable = Observable.range(1,20); // 表示发射从1开始到20的整数序列

创建一个发射特定整数序列的Observable,第一个参数为起始值,第二个为发送的个数(即调用onNext()方法次数),如果为0则不发送,负数则抛异常。
7、
timer()方式

Observable<Integer> observable = Observable.timer(1, TimeUnit.SECONDS); // 定时1秒后,发送整数1事件(调用onNext()方法)

创建一个Observable,在给定的延迟后发射一个特定的值
8、repeat()方式

Observable<Integer> observable = Observable.just(1).repeat();

创建一个Observable,该Observable的事件可以重复调用

Disposable:
用于连接管理,其dispose()方法可断开将Observer(观察者)与Observable(被观察者)之间的连接(取消订阅)

public interface Subscription {  // 1.x使用, 可向生产者请求数据,又可以取消订阅、释放资源    public void request(long n);      public void cancel();  } //Represents a disposable resource.public interface Disposable { // 2.x中替代Subscription    // Dispose the resource, the operation should be idempotent.    void dispose();    boolean isDisposed();}

Disposable获取方式

1、CompositeDisposable composite = new CompositeDisposable();composite.add(Flowable.range(1, 2).subscribeWith(subscriber)); // subscribeWith方法返回当前的Subscriber对象composite.dispose()  //取消订阅2、Disposable disposable = Observable.just("one").subscribe(new Consumer<String>() {    @Override    public void accept(String s) throws Exception {    }});disposable.dispose() //取消订阅3、DefaultSubscriber, ResourceSubscriber,DisposableSubscriber都实现了Disposable接口(资源跟踪支持)可通过它们的实例对象,调用dispose()来取消订阅//public abstract class ResourceSubscriber<T> implements FlowableSubscriber<T>, Disposable {}   ResourceSubscriber<Integer> subscriber = new ResourceSubscriber<Integer>() {    @Override    public void onStart() {        request(Long.MAX_VALUE); // 请求资源    }    @Override    public void onNext(Integer t) {        System.out.println(t);    }    @Override    public void onError(Throwable t) {        t.printStackTrace();    }    @Override    public void onComplete() {        System.out.println("Done");    }};subscriber.dispose(); //取消订阅4、Disposable disposable;Observer<String> observer = new Observer<String>() {   @Override   public void onSubscribe(Disposable d) {      disposable = d;   }};

观察者模式创建步骤:
1、订阅者(观察者)创建
2、被观察者创建,变换、线程控制设置
3、订阅
4、被观察者的事件序列发送
5、订阅者事件响应

Disposable disposable;Observable<Integer> observable = Observable.timer(1, TimeUnit.SECONDS); // 1、创建被观察者,timer()发送整数1事件(调用onNext()方法)Observer<Integer> observer = new Observer<Integer>() { // 2、观察者    @Override    public void onSubscribe(Disposable d) {        //Disposable是1.x的Subscription改名的,2.0之后新添加的        //可使用d.dispose()方法取消订阅        disposable = d;    }    @Override    public void onNext(Integer t) { // 4、接收整数事件        System.out.println(t);    }    @Override    public void onError(Throwable t) {        t.printStackTrace();    }    @Override    public void onComplete() {        System.out.println("Done");    }};observable.subscribe(observer); // 3、订阅

2、线程控制器Scheduler

RxJava遵循的是线程不变的原则:在哪个线程调用subscribe(),就在哪个线程生产、消费事件Scheduler切换线程:RxJava通过Scheduler指定代码运行在哪种线程中,RxJava内置Scheduler:Schedulers.immediate():默认的Scheduler,直接在当前线程运行。包含用于延迟动作的阻塞睡眠,并且不支持递归调度。你可以使用Schedulers.trampoline代替Schedulers.immediate()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()和observeOn()方法来对线程进行控制了。subscribeOn(): 指定Observable(被观察者、事件生产者)所在的线程。 observeOn():   指定Observer(观察者、事件消费者)所运行在的线程。

3、操作符

为解决对象变换问题而设计,操作符可以在传递的途中将事件序列中的对象或整个序列进行修改,转换成不同的事件或事件序列(用于转换Observable为其它观察者对象所期望的新的Observer的过程)map()将其转换为与之不同的对象,对应返回的Observable/Flowable对象参数也会变为转换后的对象,一对一的变换。(原来的Observable对象转换成另一个Observable对象,将传输的数据进行一些操作,以便Observer获得想要的数据形式)flatMap()flatMap可以是一对多的转换,flatmap()重新生成一个Observable对象,并把数据转换成Observer想要的数据形式filter()根据自己想过滤的数据加入相应的逻辑判断,返回true则表示数据满足条件,返回false则表示数据需要被过滤。最后过滤出的数据将加入到新的Observable对象中,方便传递给Observer想要的数据形式doOnNext()允许在每次输出一个元素之前做一些额外的事情,比如提示、保存类的操作doOnSubscribe()这个操作符跟onStart方法一样,都是在subscribe()方法调用后且事件发送之前执行,可做数据初始化操作。默认情况下,doOnSubscribe()执行在subscribe()发生的线程,如果在doOnSubscribe()之后有subscribeOn()的话,它将执行在离它最近的subscribeOn()所指定的线程中,doOnSubscribe()之后的subscribeOn()且是最近的才会影响它timer()做定时操作interval()做周期性操作lift()和compose()lift() 对事件项和事件序列,lift(Operator)//1.x public interface Operator<R, T> extends Func1<Subscriber<? super R>, Subscriber<? super T>> { }lift(Operator<? extends R, ? super T> operator)  //用来转换Subscriber  //2.x  public final <R> Single<R> lift(final SingleOperator<? extends R, ? super T> lift)compose() 对Observable自身进行变换,compose(Transformer)//1.x  public interface Transformer<T, R> extends Func1<Observable<T>, Observable<R>> { }  compose(Transformer<? super T, ? extends R> transformer)//用来转换Observable,如bindUtilEvent  //2.xpublic final <R> Flowable<R> compose(FlowableTransformer<? super T, ? extends R> composer)concat()和merge()range()第一个参数为开始值,第二个参数为数量filter()方法用于对数据进行过滤take(n)方法用于取前n个值

4、功能接口

Action:Consumer、BiConsumer、Consumer<Object[]>FunctionFunction、BiFunction、Function3-9Function<Object[],R>//泛型第一个为接收参数的数据类型,第二个为转换后要发射的数据类型

5、Flowable Backpressure
被观察者是事件的生产者,观察者是事件的消费者。当生产者不断生成事件,消费者不能实时的消费事件,造成消费者端事件堆积,Flowable(Backpressure背压–观察者端对事件缓存、处理的方式,主要操作RxJava缓存池,默认大小为128)用于解决此类问题的!

Backpressure处理策略:
ERROR
缓存池溢出,立刻抛出MissingBackpressureException异常
BUFFER
把RxJava中默认的只能存128个事件的缓存池换成一个大的缓存池,支持存很多的数据缓存
DROP
把消费者处理不了的事件丢弃
LATEST
与DROP功能基本一致。
唯一的区别就是LATEST总能使消费者能够接收到生产者产生的最后一个事件

//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,    ERROR, //Signals a MissingBackpressureException in case the downstream can't keep up.    BUFFER, //Buffers <em>all</em> onNext values until the downstream consumes it.    DROP, //Drops the most recent onNext value if the downstream can't keep up.    LATEST //Keeps only the latest onNext value, overwriting any previous value if the downstream can't keep up.}Flowable<Integer> flowable = Flowable.create(new FlowableOnSubscribe<Integer>() {    @Override    public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {        emitter.onNext(1);        emitter.onNext(2);        emitter.onComplete();    }}, BackpressureStrategy.ERROR); //1、Backpressure使用方式1,ERROR策略:异步调用时,缓存池溢出,则抛出MissingBackpressureException异常,此时消费者不能再接收事件,但生产者并不会停止事件发送Subscriber<Integer> subscriber = new Subscriber<Integer>() {    @Override    public void onSubscribe(Subscription s) {     // Subscription可用于切断观察者与被观察者间的联系(调用Subscription.cancel())        mSubscription = s; // 外部mSubscription变量赋值(外部操作该Subscription,Subscription负责流和资源的生命周期管理,即申请以及退订、释放资源),通过这种方式组织新的背压关系        s.request(Long.MAX_VALUE);  // 2.x中,onSubscribe()回调中须调用s.request()方法去请求资源(向生产者申请可接收、消费的事件数量,不显示调用request就表示消费能力为0)    }    @Override    public void onNext(Integer t) {        System.out.println(t);    }    @Override    public void onError(Throwable t) {        t.printStackTrace();    }    @Override    public void onComplete() {        System.out.println("Done");    }};flowable.subscribeOn(Schedulers.io())        .observeOn(AndroidSchedulers.mainThread())        .subscribe(subscriber); Flowable.just(1)        .onBackpressureBuffer(256) // 1、Backpressure使用方式2,onBackpressureBuffer()、onBackpressureDrop() onBackpressureLatest()        .subscribeOn(Schedulers.io())        .observeOn(AndroidSchedulers.mainThread())        .subscribe(new Consumer<Integer>() {             @Override             public void accept(Integer integer) throws Exception {                Log.d("Subscriber", "accept: " + integer);             }        });