从零学习RxJava2.0-简单入门

前言

  • 函数式编程:函数式编程是种编程方式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ演算(lambda calculus),而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值),和指令式编程相比,函数式编程强调函数的计算比指令的执行重要。和过程化编程相比,函数式编程里函数的计算可随时调用。

RXJava

  • 当我们的异步网络请求用的越来越多的时候,rxjava是一种能依旧让我们的逻辑保持清晰的操作,他的原理就是创建一个Observable对象来干活,然后使用各种操作符建立起来的链式操作,就如同流水线一样,把你的数据一步一步加工,最终达到想要的效果。
  • rxjava的异步操作是通过扩展的观察者模式来实现的,rxjava有四个角色,Observable,Observer,Subscriber和Subject,其中Observable和Observer通过Subscriber方法实现订阅关系,Observable就可以在需要的时候通知Observer。
  • 其实RxJava是通过扩展的观察者模式来实现的,不了解观察者模式的童鞋可以移驾这里
  • emmmmm,还是等会代码解释

使用前添加依赖

implementation "io.reactivex.rxjava2:rxjava:2.x.y"
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
  • 具体版本直接上git官方查看就ok
  • 其中RxAndroid是RxJava在android平台上的扩展,它包含了一些能够简化Android开发的工具,比如特殊的调度器

一.使用入门

  • 基本用法分三步

1.创建Observer(观察者)

  • 他决定事件触发时的行为,先看看怎么创建
Observer<String> mObserver = new Observer<String>() {
        @Override
        public void onSubscribe(Disposable d) {

        }

        @Override
        public void onNext(String s) {
            Log.d(TAG, "onNext: 我是张三,他给我发的消息是 message  = " +s );
        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onComplete() {

        }
    };
  • 先不说他的具体运行步骤,我们先往下看

2.创建被观察者(Observable)

Observable<String> mObservable = Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> emitter) throws Exception {
            //执行一些其他操作
            //.............
            //执行完毕,触发回调,通知观察者
            emitter.onNext("这是第一条消息");
            emitter.onNext("我来发射数据");
            emitter.onComplete();
        }
    });
  • 再往下看,实现订阅

3.订阅(subscribe)

mObservable.subscribe(mObserver);
  • 订阅的方式很简单,就是用被观察者调用subscribe方法来订阅观察者

4.运作方式

  • 在我们订阅的时候,实际上就是调用的被观察者在创建的时候我们实现的ObservableOnSubscribe接口的匿名类的subscriber方法
  • 不过此时并不是立即调用我们实现的subscribe方法里面的逻辑,先调用的是观察者的onSubscribe方法
  • 然后再去运行Subscribe方法里面的逻辑
  • 而Subscribe方法的参数emitter实际上就是我们在订阅的时候传入的观察者实例
  • 所以我们在被观察者里面调用的emitter.onNext(“这是第一条消息”);实际上就是回调的是观察者的onNext方法
  • 当运行异常的时候,观察者的onError方法就会被调用,同时事件队列自动终止,不允许再有事件发出
  • complete方法是在事件完毕之后执行,不过在这种方式之下我们需要手动去调用,就像我上面写的

5.其他的创建被观察者的方式

(1).Just方式

mObservable = Observable.just("这是just方式创建的被观察者发送的事件");
  • 这里的just参数将直接被作为Onserver的onNext方法的参数传入
  • 所以在mObservable.subscribe(mObserver);之后,log打印出来的信息就是
onSubscribe: 
onNext: 我是张三,他给我发的消息是 message  = 这是just方式创建的被观察者发送的事件
onComplete: 
  • 这里不清楚为什么这里的complete方法得到了执行,百思不得其解
  • 这里的just方式是重载了十个方法,分别对应一个参数,两个参数,…一直到十个参数

(2).formLiterable方式

List<String> list = new ArrayList<>();
for(int i = 0 ; i < 10 ;i++){
     list.add("我是formIterable方式创建的第  " + i+ "   条消息");
}
mObservable = Observable.fromIterable((Iterable<String>)list);
  • 订阅之后,得到的log为
onSubscribe: 
onNext: 我是张三,他给我发的消息是 message  = 我是formIterable方式创建的第  0   条消息
onNext: 我是张三,他给我发的消息是 message  = 我是formIterable方式创建的第  1   条消息
onNext: 我是张三,他给我发的消息是 message  = 我是formIterable方式创建的第  2   条消息
onNext: 我是张三,他给我发的消息是 message  = 我是formIterable方式创建的第  3   条消息
onNext: 我是张三,他给我发的消息是 message  = 我是formIterable方式创建的第  4   条消息
onNext: 我是张三,他给我发的消息是 message  = 我是formIterable方式创建的第  5   条消息
onNext: 我是张三,他给我发的消息是 message  = 我是formIterable方式创建的第  6   条消息
onNext: 我是张三,他给我发的消息是 message  = 我是formIterable方式创建的第  7   条消息
onNext: 我是张三,他给我发的消息是 message  = 我是formIterable方式创建的第  8   条消息
onNext: 我是张三,他给我发的消息是 message  = 我是formIterable方式创建的第  9   条消息
onComplete: 
  • 所以说,这里的list集合其实就相当于我们上面在just里面传入的多条参数
  • 而且, Collection接口是Iterable接口的子接口,所以所有Collection接口的实现类都可以作为Iterable对象直接传入fromIterable()方法。

(3).defer方式

mObservable = Observable.defer(new Callable<ObservableSource<? extends String>>() {
    @Override
    public ObservableSource<? extends String> call() throws Exception {
        return Observable.just("我是defer方式创建的被观察者","我也是defer方式创建的被观察者");
    }
});
  • 打印出的log信息为
onSubscribe: 
onNext: 我是张三,他给我发的消息是 message  = 我是defer方式创建的被观察者
onNext: 我是张三,他给我发的消息是 message  = 我也是defer方式创建的被观察者
onComplete: 

(4).interval方式

Observable<Long> o = Observable.interval(4, TimeUnit.SECONDS);
o.subscribe(new Observer<Long>() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.d(TAG, "interval方式创建 onSubscribe: ");
    }

    @Override
    public void onNext(Long aLong) {
        Log.d(TAG, "interval方式创建 onNext: 他给我发的数字是 " + aLong);
    }

    @Override
    public void onError(Throwable e) {
        Log.d(TAG, "interval方式创建 onError: ");
    }

    @Override
    public void onComplete() {
        Log.d(TAG, "interval方式创建 onComplete: ");
    }
});
  • 这种方式的作用时就像定时器一样,按照我们在interval里面设置的时长间隔发送从0开始的整数序列
  • 因为他所需要的泛型是长整型,所以这里我重新创建了一个被观察者,并且在订阅的时候重新创建了一个观察者,由于我在interval里面写的是4,TimeUnit.SECONDS,所以他将每隔四秒发送一个整型值,所以打出的log为
interval方式创建 onSubscribe: 
interval方式创建 onNext: 他给我发的数字是 0
interval方式创建 onNext: 他给我发的数字是 1
interval方式创建 onNext: 他给我发的数字是 2
interval方式创建 onNext: 他给我发的数字是 3
interval方式创建 onNext: 他给我发的数字是 4
interval方式创建 onNext: 他给我发的数字是 5
interval方式创建 onNext: 他给我发的数字是 6
  • 这个方法正常情况是不会主动执行complete方法的,因为他会一直发送下去

(5).range方式

Observable<Integer> observable = Observable.range(1,5);
observable.subscribe(new Observer<Integer>() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.d(TAG, "onSubscribe: ");
    }

    @Override
    public void onNext(Integer integer) {
        Log.d(TAG, "onNext: 这次他发送的数字是 " + integer);
    }

    @Override
    public void onError(Throwable e) {
        Log.d(TAG, "onError: ");
    }

    @Override
    public void onComplete() {
        Log.d(TAG, "onComplete: ");
    }
});
  • 还是因为他只接受整型或长整型泛型的Observer,所以我重新创建了观察者
  • 其中range的第一个参数表示开始发送的数字,第二个参数表示发送的个数,看一下log的信息
onSubscribe: 
onNext: 这次他发送的数字是 1
onNext: 这次他发送的数字是 2
onNext: 这次他发送的数字是 3
onNext: 这次他发送的数字是 4
onNext: 这次他发送的数字是 5
onComplete: 
  • 其中,第二个参数不可以为负值,当为0时就不打印

(7).Timer方式

Observable<Long> observable1 = Observable.timer(2, TimeUnit.SECONDS);
observable1.subscribe(mLongObserver);
  • 啊,这里我没再去创建一个Long泛型的Observer,而是在外面创建了一个私有变量,啊,这些不管
  • 这种方式的timer的参数为延迟第一个参数为第二个参数为单位的时间,发送一个东西(额,我也不知道发什么东西,反正就是延迟这么长时间,调用观察者的onNext方法)
  • 看一下他的log信息
onSubscribe: 
onNext: 0
onComplete: 

(8).repeat方式

  • 这种方式就是将以上几种方式一直重复,比如说我重复TImer
Observable<Long> observable2 = Observable.timer(3, TimeUnit.SECONDS).repeat();
observable2.subscribe(new Observer<Long>() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.d(TAG, "onSubscribe: ");
    }

    @Override
    public void onNext(Long integer) {
        Log.d(TAG, "onNext: "  + integer);
    }

    @Override
    public void onError(Throwable e) {
        Log.d(TAG, "onError: ");
    }

    @Override
    public void onComplete() {
        Log.d(TAG, "onComplete: ");
    }
});
  • 打印出的log为
onSubscribe: 
onNext: 0
onNext: 0
onNext: 0
onNext: 0
onNext: 0
onNext: 0
  • 那么他就会一直重复Timer这个动作,至于其他的也一样,只需要给后面加一个repeat就可以

6.简单部分补充

  • 我们在使用订阅方法的时候,常常看到有好几个重载的subscriber方法
public final Disposable subscribe() {}
表示观察者不对被观察者发送的事件作出任何响应(但被观察者还是可以继续发送事件)
public final Disposable subscribe(Consumer<? super T> onNext) {}
表示观察者只对被观察者发送的Next事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {}
表示观察者只对被观察者发送的Next事件 & Error事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {}
表示观察者只对被观察者发送的Next事件、Error事件 & Complete事件作出响应
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Consumer<? super Disposable> onSubscribe) {}
表示观察者只对被观察者发送的Next事件、Error事件 、Complete事件 & onSubscribe事件作出响应
public final void subscribe(Observer<? super T> observer) {}
表示观察者对被观察者发送的任何事件都作出响应
  • 我们可以看到,最后一种是我们基本使用的那种
  • 第一种表示当调用之后,只调用被观察者实现的subscribe方法中除过事件之外的其他语句
  • 比方说
mObservable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                //执行一些其他操作
                //.............
                //执行完毕,触发回调,通知观察者
                Log.d(TAG, "subscribe: 我要发送第一条消息啦");
                emitter.onNext("这是第一条消息");
                Log.d(TAG, "subscribe: 我要发送第二条消息啦");
                emitter.onNext("我来发射数据");
            }
        });
  • 如果我们的被观察者这样写,那么当mObservable.subscriber()之后,只会执行两个log语句,而不会指向其他的两个语句
  • 第二个到第四个方法,代表我们只实现简单的观察者,这里我写全的最后一个方法的调用方式为
Observable<String> observable = Observable.just("我是消息");
observable.subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Exception {
        Log.d(TAG, "accept: " + s);
    }
}, new Consumer<Throwable>() {
    @Override
    public void accept(Throwable throwable) throws Exception {
        Log.d(TAG, "accept: Error");
    }
}, new Action() {
    @Override
    public void run() throws Exception {
        Log.d(TAG, "run: complete");
    }
}, new Consumer<Disposable>() {
    @Override
    public void accept(Disposable disposable) throws Exception {
        Log.d(TAG, "accept: Subscriber");
    }
});
  • 其中,subscriber方法第一第二第四个参数分别实现Consumer接口,第三个参数实现Action接口
  • 当我按照上面所写的话,打印出来的log为
accept: Subscriber
accept: 我是消息
run: complete
  • 可以看出,第一个参数表示我们观察者的onNext方法调用,第二个相当于onError方法调用,第三个参数代表complete方法调用,第四个参数相当于subscriber方法调用
  • 由四个不同的重载方法比较得出,我们可以只实现第一个参数的方法,那么他相当于只执行观察者的onNext方法,以此类推

7.中断观察者与被观察者的连接

  • 通过这种方式我们可以中断观察者与被观察者的连接,也就是说被观察者你爱发不发,我都可以通过这种方式来不去接收你的消息
Observable<String> observable = Observable.just("我是消息1","我是消息2","我是消息3","我是消息4");
        observable.subscribe(new Observer<String>() {
            //这是拦截器
            private Disposable mDisposable;
            private int cnt = 0;
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "onSubscribe: 拦截器赋值");
                mDisposable = d;
            }

            @Override
            public void onNext(String s) {
                cnt++;
                Log.d(TAG, "onNext: 我收到了第 "+ cnt +" 条消息 == "+s);
                if(cnt  >  2){
                    Log.d(TAG, "onNext: 好了,我已经中断连接了");
                    mDisposable.dispose();
                }
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "onError: ");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "onComplete: ");
            }
        });
  • 打印出来的log信息为
onSubscribe: 拦截器赋值
onNext: 我收到了第 1 条消息 == 我是消息1
onNext: 我收到了第 2 条消息 == 我是消息2
onNext: 我收到了第 3 条消息 == 我是消息3
onNext: 好了,我已经中断连接了
  • 在中断之后就不会执行complete方法了

8.简单小结

  • 可以看到,RxJava的整个运作流程大概是这样的
  • 被观察者 (Observable) 通过 订阅(Subscribe) 按顺序发送事件 给观察者 (Observer), 观察者(Observer) 按顺序接收事件 & 作出对应的响应动作
  • 同时我们也可以分开分别实现带四个参数的subscriber方法,将我们的观察者的四个方法分开
  • 同时,在合适的地方采取合适的中断连接等等

猜你喜欢

转载自blog.csdn.net/asffghfgfghfg1556/article/details/81209506