RXJava 全面学习笔记(中)

本文篇幅较长 建议收藏起来等时间空闲详细阅读
本篇文章主要是一份学习笔记

线程控制(切换/调度)

  • 线程控制的作用: 指定被观察者(observable) 和observer(观察者)的工作线程类型

  • 线程控制的背景: 在RxJava模型中,被观察者(observable)和观察者(observer)的工作线程=创建自身的线程

    1. 即若被观察者在主线程中被创建,那么他们的工作就会发生在主线程
    2. 因为创建被观察者/观察者的线程=主线程
    3. 所以产生时间/接受&响应事件都发生在主线程
  • 线程控制冲突:

    • 对于一般的需求场景,需要在子线程中实现耗时操作,然后回到主线程实现UI操作
      1. 被观察者在子线程中产生事件(如实现耗时操作)
      2. 观察者在主线程接受&响应事件(实现UI操作)
  • 冲突的解决方案

    所以为了解决线程冲突,实现真正的异步操作,我们对RxJava进行线程控制

  • 实现方式

    采用RxJava内置的线程调度器(Scheduler),即通过功能性的操作符subscribeon()&observeon()实现

    • subscribeOn()&observeOn()简介

      作用:线程控制,指定观察者或者被观察者的工作线程类型

      类型含义应用场景
      Schedulers.immediate()当前线程: =不指定线程默认情况
      AndroidSchedulers.mainThread()Android主线程操作UI
      Schedulers.newThread()常规新线程耗时操作
      Schedulers.io()io操作线程网络请求,读写文件等io秘籍型操作
      Schedulers.computation()CPU计算操作线程大量计算操作

      RxJava内部使用线程池来维护这些线程,所以线程的调度效率非常高.

    • 具体使用

      具体是在通过订阅(subscribe)连接观察者和被观察者中实现

      <-- 使用说明 -->
        // Observable.subscribeOn(Schedulers.Thread):指定被观察者 发送事件的线程(传入RxJava内置的线程类型)
        // Observable.observeOn(Schedulers.Thread):指定观察者 接收 & 响应事件的线程(传入RxJava内置的线程类型)
      
      <-- 实例使用 -->
      // 步骤3:通过订阅(subscribe)连接观察者和被观察者
              observable.subscribeOn(Schedulers.newThread()) // 1. 指定被观察者 生产事件的线程
                        .observeOn(AndroidSchedulers.mainThread())  // 2. 指定观察者 接收 & 响应事件的线程
                        .subscribe(observer); // 3. 最后再通过订阅(subscribe)连接观察者和被观察者
      
      

      注意

      • 若observable.subscribeOn()多次指定被观察者生产事件的线程,则只有第一次指定有效,其余的指定线程无效

      • 若Observable.observeOn()多次指定观察者接受&响应事件的线程,则每次指定均有效,即每指定一次观察者,就会进行一次线程的切换

        // 步骤3:通过订阅(subscribe)连接观察者和被观察者
                observable.subscribeOn(Schedulers.newThread())
                          .observeOn(AndroidSchedulers.mainThread()) // 第一次指定观察者线程 = 主线程
                          .doOnNext(new Consumer<Integer>() { // 生产事件
                            @Override
                            public void accept(Integer integer) throws Exception {
                                Log.d(TAG, "第一次观察者Observer的工作线程是: " + Thread.currentThread().getName());
                            }
                        })
                        .observeOn(Schedulers.newThread()) // 第二次指定观察者线程 = 新的工作线程
                        .subscribe(observer); // 生产事件
        
        
        // 注:
        // 1. 整体方法调用顺序:观察者.onSubscribe()> 被观察者.subscribe()> 观察者.doOnNext()>观察者.onNext()>观察者.onComplete() 
        // 2. 观察者.onSubscribe()固定在主线程进行
        

功能性的操作符

  • 作用: 辅助被观察者(observable)在发送事件时实现一些功能性性需求 如错误处理,线程调度

  • 类型:

    类型作用
    连接观察者和被观察者(订阅者)subscribe
    线程调度subscribeOn
    observeon
    延迟操作delay
    在事件的生命周期中操作do()操作符
    错误处理onErrorReturn
    onErrorResumeNext
    onExceptResumenext
    retry
    retryUntil
    retyWhen
    重复发送repeat
    repeatWhen
  • 连接被观察者和观察者 形成订阅关系

    • subscribe()

      observable.subscribe(observer);
      // 前者 = 被观察者(observable);后者 = 观察者(observer 或 subscriber)
      
      
      <-- 1. 分步骤的完整调用 -->
      //  步骤1: 创建被观察者 Observable 对象
              Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
                  @Override
                  public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                      emitter.onNext(1);
                      emitter.onNext(2);
                      emitter.onNext(3);
                      emitter.onComplete();
                  }
              });
      
      // 步骤2:创建观察者 Observer 并 定义响应事件行为
              Observer<Integer> observer = new Observer<Integer>() {
                  // 通过复写对应方法来 响应 被观察者
                  @Override
                  public void onSubscribe(Disposable d) {
                      Log.d(TAG, "开始采用subscribe连接");
                  }
                  // 默认最先调用复写的 onSubscribe()
      
                  @Override
                  public void onNext(Integer value) {
                      Log.d(TAG, "对Next事件"+ value +"作出响应"  );
                  }
      
                  @Override
                  public void onError(Throwable e) {
                      Log.d(TAG, "对Error事件作出响应");
                  }
      
                  @Override
                  public void onComplete() {
                      Log.d(TAG, "对Complete事件作出响应");
                  }
              };
      
              
              // 步骤3:通过订阅(subscribe)连接观察者和被观察者
              observable.subscribe(observer);
      
      
      <-- 2. 基于事件流的链式调用 -->
              Observable.create(new ObservableOnSubscribe<Integer>() {
              // 1. 创建被观察者 & 生产事件
                  @Override
                  public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                      emitter.onNext(1);
                      emitter.onNext(2);
                      emitter.onNext(3);
                      emitter.onComplete();
                  }
              }).subscribe(new Observer<Integer>() {
                  // 2. 通过通过订阅(subscribe)连接观察者和被观察者
                  // 3. 创建观察者 & 定义响应事件的行为
                  @Override
                  public void onSubscribe(Disposable d) {
                      Log.d(TAG, "开始采用subscribe连接");
                  }
                  // 默认最先调用复写的 onSubscribe()
      
                  @Override
                  public void onNext(Integer value) {
                      Log.d(TAG, "对Next事件"+ value +"作出响应"  );
                  }
      
                  @Override
                  public void onError(Throwable e) {
                      Log.d(TAG, "对Error事件作出响应");
                  }
      
                  @Override
                  public void onComplete() {
                      Log.d(TAG, "对Complete事件作出响应");
                  }
      
              });
          }
      }
      <-- Observable.subscribe(Subscriber) 的内部实现 -->
        public Subscription subscribe(Subscriber subscriber) {
          subscriber.onStart();
          // 在观察者 subscriber抽象类复写的方法 onSubscribe.call(subscriber),用于初始化工作
          // 通过该调用,从而回调观察者中的对应方法从而响应被观察者生产的事件
          // 从而实现被观察者调用了观察者的回调方法 & 由被观察者向观察者的事件传递,即观察者模式
          // 同时也看出:Observable只是生产事件,真正的发送事件是在它被订阅的时候,即当 subscribe() 方法执行时
      }
      
    • 线程调度 :参考下文

    • 延迟操作 delay()

      // 1. 指定延迟时间
      // 参数1 = 时间;参数2 = 时间单位
      delay(long delay,TimeUnit unit)
      
      // 2. 指定延迟时间 & 调度器
      // 参数1 = 时间;参数2 = 时间单位;参数3 = 线程调度器
      delay(long delay,TimeUnit unit,mScheduler scheduler)
      
      // 3. 指定延迟时间  & 错误延迟
      // 错误延迟,即:若存在Error事件,则如常执行,执行后再抛出错误异常
      // 参数1 = 时间;参数2 = 时间单位;参数3 = 错误延迟参数
      delay(long delay,TimeUnit unit,boolean delayError)
      
      // 4. 指定延迟时间 & 调度器 & 错误延迟
      // 参数1 = 时间;参数2 = 时间单位;参数3 = 线程调度器;参数4 = 错误延迟参数
      delay(long delay,TimeUnit unit,mScheduler scheduler,boolean delayError): 指定延迟多长时间并添加调度器,错误通知可以设置是否延迟
      
    • 在事件的生命周期中操作 do()

      do()操作符有很多个.

      当observable没发送一次数据事件就会调用一次doOnEach
      包含onNext,onError和onComplete
      Next事件doOnNext(执行next事件之前调用)
      doAfterNext(执行next事件只后调用)
      发送事件完毕后调用doOnError(发送错误时)
      doOnComplete(发送事件完毕之后)
      doOnTerminate(无论正常发送完毕之后/异常终止)
      doOnFinally(最后执行)
      订阅相关doOnSubscribe(观察者订阅时调用)
      doOnUnsubscribe(观察者取消订阅时调用)
    • 错误处理

      • onErrorReturn() 遇到错误时,发送一个特殊事件&正常终止

      • onErrorResumeNext() 遇到错误时,发送一个新的observable

        1. onErrorResumeNext拦截错误=throwable 若需要拦截Exception请用onExceptionResumenext();
        2. 若用onErrorResumeNext拦截的错误=Exception,则会将错误传递给观察者的onError方法
      • onExceptionResumeNext(); 遇到错误,发送一个新的observable

        1. onExceptionResumeNext拦截的错误=Exception,若需要拦截Throwable请用onErrorResumeNext
        2. 若用onExceptionResumeNext拦截的错误=Throwable,则会将错误传递给观察者的onError方法
      • retry 重试:

        1. 接受到onError()时,重新订阅&发送

        2. Throwable和Exception都可以拦截

          <-- 1. retry() -->
          // 作用:出现错误时,让被观察者重新发送数据
          // 注:若一直错误,则一直重新发送
          
          <-- 2. retry(long time) -->
          // 作用:出现错误时,让被观察者重新发送数据(具备重试次数限制
          // 参数 = 重试次数
           
          <-- 3. retry(Predicate predicate) -->
          // 作用:出现错误后,判断是否需要重新发送数据(若需要重新发送& 持续遇到错误,则持续重试)
          // 参数 = 判断逻辑
          
          <--  4. retry(new BiPredicate<Integer, Throwable>-->
          // 作用:出现错误后,判断是否需要重新发送数据(若需要重新发送 & 持续遇到错误,则持续重试
          // 参数 =  判断逻辑(传入当前重试次数 & 异常错误信息)
          
          <-- 5. retry(long time,Predicate predicate) -->
          // 作用:出现错误后,判断是否需要重新发送数据(具备重试次数限制
          // 参数 = 设置重试次数 & 判断逻辑
          
      • retryUntil 出现错误后,判断是否需要重新发送数据

        具体使用类似retry,唯一区别返回true时,则不重新发送数据事件,

      • retryWhen 遇到错误将发生的错误传递给一个新的观察者(observable),并决定是否需要重新订阅原始被观察者(observer)&发送事件

    • 重复发送

      • repeat 重复不断地发送被观察者事件 无条件 具备重载方法,可设置重复创建次数
      • repeatWhen 有条件,重复发送被观察者事件
        1. 若新被观察者observable返回一个complete/error事件,则不重新订阅&发送原来的observable
        2. 若新被观察者observable返回其余事件时,则重新订阅&发送原来的observable

    总结

    img

过滤操作符

  • 作用: 过滤/筛选被观察者发送的事件&观察者接收的事件

  • 类型

    根据指定条件过滤事件filter
    ofType
    ship
    skiplast
    disinct
    disinctUntilChanged
    根据指定事件数量过滤事件take
    takeLast
    根据指定时间过滤事件throttleFirst
    throttlelast
    Sample
    throttleWithTimeOut
    debounce
    根据指定事件位置过滤事件firstElement
    lastElement
    elementAt
    elementAtError
  • 根据指定条件过滤事件

    需求: 通过指定的过滤条件,当且仅当事件满足条件,就将该事件过滤(不发送)

    1. filter 过滤特定条件的事件

       Observable.create((ObservableOnSubscribe<Integer>) emitter -> {
                  emitter.onNext(1);
                  emitter.onNext(10);
                  emitter.onNext(100);
                  emitter.onNext(1000);
                  emitter.onNext(10000);
              }).filter((AppendOnlyLinkedArrayList.NonThrowingPredicate<Integer>) integer -> integer > 3)
                      .subscribe(integer -> Log.d("admin", "过滤后得到的事件是:" + integer));
      
    2. ofType 过滤特定数据类型数据

        Observable.just("12",15,'a',189.02,15.01,"dad").ofType(Double.class).subscribe(aDouble ->
                  Log.d("admin","获取到的整型事件元素是: "+ aDouble));
      
    3. skip/skipLast 跳过某个事件

      // 使用1:根据顺序跳过数据项
              Observable.just(1, 2, 3, 4, 5)
                      .skip(1) // 跳过正序的前1项
                      .skipLast(2) // 跳过正序的后2项
                        .subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept( Integer integer) throws Exception {
                                Log.d(TAG,"获取到的整型事件元素是: "+ integer);
                            }
              });
      
      // 使用2:根据时间跳过数据项
              // 发送事件特点:发送数据0-5,每隔1s发送一次,每次递增1;第1次发送延迟0s
              Observable.intervalRange(0, 5, 0, 1, TimeUnit.SECONDS)
                      .skip(1, TimeUnit.SECONDS) // 跳过第1s发送的数据
                      .skipLast(1, TimeUnit.SECONDS) // 跳过最后1s发送的数据
                      .subscribe(new Consumer<Long>() {
      
                          @Override
                          public void accept( Long along ) throws Exception {
                              Log.d(TAG,"获取到的整型事件元素是: "+ along);
                          }
                      });
      
    4. distinct/distinctUntilChanged 过滤事件序列中重复的事件/连续的事件

      // 使用1:过滤事件序列中重复的事件
              Observable.just(1, 2, 3, 1 , 2 )
                      .distinct()
                      .subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept( Integer integer) throws Exception {
                                Log.d(TAG,"不重复的整型事件元素是: "+ integer);
                            }
              });
      
              // 使用2:过滤事件序列中 连续重复的事件
              // 下面序列中,连续重复的事件 = 3、4
              Observable.just(1,2,3,1,2,3,3,4,4 )
                      .distinctUntilChanged()
                      .subscribe(new Consumer<Integer>() {
                          @Override
                          public void accept( Integer integer) throws Exception {
                              Log.d(TAG,"不连续重复的整型事件元素是: "+ integer);
                          }
                      });
      
  • 根据指定事件数量过滤事件

    通过设置指定的事件数量,仅发送特定数量的事件

    1. take 指定观察者最多能接收到的事件数量
    2. takeLast 指定观察者只能接受到被观察者发送的最后几个事件
  • 根据指定时间过滤事件

    通过设置指定时间,仅发送在该时间内的事件

    1. throttleFirst/ throttleLast 在某段时间内,只能发送该段时间内第一次事件/最后一次事件 如1段时间内连续点击按钮,但只执行第一次的点击操作
    2. Smple 在某段时间内,只发送该段时间内最新(最后)1次事件 类似于throeeleLast操作符
    3. throttleWithTimeout / debounce 发送数据事件时,若2次发送事件的间隔<指定时间,就会丢弃前一次数据,直到指定时间内都没有新数据发射时才会发送最后一次的数据
  • 根据指定事件位置过滤事件

    通过设置指定位置,过滤在该位置的事件

    1. firstElement/ lastElement 仅选取第一个元素/最后一个元素(无参数)
    2. elementAt 指定接收某个元素(通过索引值确定) 允许越界,
    3. elementAtOrError 当出现越界情况时,即抛出异常.

功能防抖

  • 功能防抖, 背景: 用户只需要使用功能1次.

  • 冲突: 但是由于外部原因,多次触发了这个功能,导致出现冗余功能操作,

  • 解决方案: 通过根据指定时间过滤事件的过滤操作符实现,防止功能的抖动

     //使用rxbinding配合rxjava 实现2秒内点击事件只会记录第一次点击
    RxView.clicks(btnSub).throttleFirst(2, TimeUnit.SECONDS).subscribe(o ->
                    Log.e("admin", o.toString())
            );
    

联想搜索功能

  • 背景: 即当用户输入1个字符,显示当前输入框字符相关的搜索结果

  • 冲突: 在用户搜索需求明确下,可能会发送一些不必要的网络请求, 如想搜索abc 其时则会发送a ab abc 三个请求

  • 解决方案: 通过指定时间过滤事件的过滤操作符 debounce实现,

            /*
             * 说明
             * 1. 此处采用了RxBinding:RxTextView.textChanges(name) = 对对控件数据变更进行监听(功能类似TextWatcher),需要引入依赖:compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
             * 2. 传入EditText控件,输入字符时都会发送数据事件(此处不会马上发送,因为使用了debounce())
             * 3. 采用skip(1)原因:跳过 第1次请求 = 初始输入框的空字符状态 
             **/
      RxTextView.textChanges(edName).debounce(1, TimeUnit.SECONDS)
                    .skip(1).observeOn(AndroidSchedulers.mainThread())
                    .subscribe(charSequence -> Log.e("admin", "发送给服务器的字符串为:" + charSequence));
                    
                    //如果skip(1)去掉log如下:
    12-19 04:34:27.492 6580-6580/com.yishion.demo_count E/admin: 发送给服务器的字符串为:
    12-19 04:34:21.657 6580-6580/com.yishion.demo_count E/admin: 发送给服务器的字符串为:11111
    
    

条件/布尔操作符

  • all 用来判断发送的每项数据是否都满足,设置函数条件(满足返回True)

    Observable.just(1,2,3,4,5,6)
                    .all(new Predicate<Integer>(){
                        @Override
                        public boolean test( Integer integer) throws Exception {
                            return (integer<=10);
                            // 该函数用于判断Observable发送的10个数据是否都满足integer<=10
                        }
                    }).subscribe(new Consumer<Boolean>() {
                @Override
                public void accept(Boolean aBoolean) throws Exception {
                    Log.d(TAG,"result is "+ aBoolean);
                    // 输出返回结果
                }
    
            });
    
  • takeWhile 判断发送的每项数据都是否满足,设置函数条件(若发送的数据满足条件,则发送该项数据)

    // 1. 每1s发送1个数据 = 从0开始,递增1,即0、1、2、3
            Observable.interval(1, TimeUnit.SECONDS)
                    // 2. 通过takeWhile传入一个判断条件
                    .takeWhile(new Predicate<Long>(){
                        @Override
                        public boolean test( Long integer) throws Exception {
                            return (integer<3);
                            // 当发送的数据满足<3时,才发送Observable的数据
                        }
                    }).subscribe(new Observer<Long>() {
                @Override
                public void onSubscribe(Disposable d) {
                }
    
                @Override
                public void onNext(Long value) {
                    Log.d(TAG,"发送了事件 "+ value);
                }
    
                @Override
                public void onError(Throwable e) {
                }
    
                @Override
                public void onComplete() {
                }
            });
    
  • shipWhile 判断发送的每项数据是否满足,设置函数条件 (直到改判断条件=false时,才开始发送observable的数据)

    // 1. 每隔1s发送1个数据 = 从0开始,每次递增1
            Observable.interval(1, TimeUnit.SECONDS)
                    // 2. 通过skipWhile()设置判断条件
                    .skipWhile(new Predicate<Long>(){
                        @Override
                        public boolean test( Long aLong) throws Exception {
                            return (aLong<5);
                            // 直到判断条件不成立 = false = 发射的数据≥5,才开始发送数据
                        }
                    }).subscribe(new Observer<Long>() {
                @Override
                public void onSubscribe(Disposable d) {
                }
    
                @Override
                public void onNext(Long value) {
                    Log.d(TAG,"发送了事件 "+ value);
                }
    
                @Override
                public void onError(Throwable e) {
                }
    
                @Override
                public void onComplete() {
                }
            });
    
    
  • takeUntil 执行到某个条件时,停止发送事件

    // 1. 每1s发送1个数据 = 从0开始,递增1,即0、1、2、3
            Observable.interval(1, TimeUnit.SECONDS)
                    // 2. 通过takeUntil的Predicate传入判断条件
                    .takeUntil(new Predicate<Long>(){
                        @Override
                        public boolean test( Long integer) throws Exception {
                            return (integer>3);
                            // 返回true时,就停止发送事件
                            // 当发送的数据满足>3时,就停止发送Observable的数据
                        }
                    }).subscribe(new Observer<Long>() {
                @Override
                public void onSubscribe(Disposable d) {
                }
    
                @Override
                public void onNext(Long value) {
                    Log.d(TAG,"发送了事件 "+ value);
                }
    
                @Override
                public void onError(Throwable e) {
                }
    
                @Override
                public void onComplete() {
                }
            });
    //该判断条件也可以是observable 即等到takeUntil传入observable开始发送数据,第一个observable的数据停止发送数据
    
  • skipUntil 等到skipUntil传入的observable开始发送数据,第一个observable的数据才开始发送数据

    // (原始)第1个Observable:每隔1s发送1个数据 = 从0开始,每次递增1
            Observable.interval(1, TimeUnit.SECONDS)
                    // 第2个Observable:延迟5s后开始发送1个Long型数据
                    .skipUntil(Observable.timer(5, TimeUnit.SECONDS))
                    .subscribe(new Observer<Long>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            Log.d(TAG, "开始采用subscribe连接");
                        }
    
                        @Override
                        public void onNext(Long value) {
                            Log.d(TAG, "接收到了事件"+ value  );
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            Log.d(TAG, "对Error事件作出响应");
                        }
    
                        @Override
                        public void onComplete() {
                            Log.d(TAG, "对Complete事件作出响应");
                        }
    
                    });
    
  • sequenceEqual 判断二个observable需要发送的数据是否相同 返回true和fasle

    Observable.sequenceEqual(
                    Observable.just(4,5,6),
                    Observable.just(4,5,6)
            )
                    .subscribe(new Consumer<Boolean>() {
                        @Override
                        public void accept( Boolean aBoolean) throws Exception {
                            Log.d(TAG,"2个Observable是否相同:"+ aBoolean);
                            // 输出返回结果
                        }
                    });
    
  • contains 判断发送的数据汇总是否包含指定数据

    Observable.just(1,2,3,4,5,6)
                    .contains(4)
                    .subscribe(new Consumer<Boolean>() {
                @Override
                public void accept(Boolean aBoolean) throws Exception {
                    Log.d(TAG,"result is "+ aBoolean);
                    // 输出返回结果
                }
    
            });
    
  • isEmpty 判断发送的2数据是否为空

    Observable.just(1,2,3,4,5,6)
              .isEmpty() // 判断发送的数据中是否为空
            }).subscribe(new Action1<Boolean>() {
                @Override
                public void call(Boolean aBoolean) {
                    Log.d(TAG,"result is "+ aBoolean); 
                    // 输出返回结果
                }
            });
    
  • amb 当需要发送福讴歌observable时,只发送先发送数据的observable的数据,而其余observable则被丢弃

    // 设置2个需要发送的Observable & 放入到集合中
            List<ObservableSource<Integer>> list= new ArrayList <>();
            // 第1个Observable延迟1秒发射数据
            list.add( Observable.just(1,2,3).delay(1,TimeUnit.SECONDS));
            // 第2个Observable正常发送数据
            list.add( Observable.just(4,5,6));
    
            // 一共需要发送2个Observable的数据
            // 但由于使用了amba(),所以仅发送先发送数据的Observable
            // 即第二个(因为第1个延时了)
            Observable.amb(list).subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    Log.e(TAG, "接收到了事件 "+integer);
                }
            });
    
  • defaultEmpty 在不发送任何有效时间,仅发送了complete时间的前提下,发送一个默认值

    Observable.create(new ObservableOnSubscribe<Integer>() {
                @Override
                public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                    // 不发送任何有效事件
                    //  e.onNext(1);
                    //  e.onNext(2);
    
                    // 仅发送Complete事件
                    e.onComplete();
                }
            }).defaultIfEmpty(10) // 若仅发送了Complete事件,默认发送 值 = 10
                    .subscribe(new Observer<Integer>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            Log.d(TAG, "开始采用subscribe连接");
                        }
    
                        @Override
                        public void onNext(Integer value) {
                            Log.d(TAG, "接收到了事件"+ value  );
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            Log.d(TAG, "对Error事件作出响应");
                        }
    
                        @Override
                        public void onComplete() {
                            Log.d(TAG, "对Complete事件作出响应");
                        }
                    });
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值