Rxjava学习笔记

Rxjava学习

Rxjava是jvm实现的响应式扩展,是一个基于观察者模式和处理异步的一个项目。

Rxjava1.0

参考:扔物线https://gank.io/post/560e15be2dca930e00da1083

准备
//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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值