Android——深入浅出RxJava 和RxAndroid(操作符)

接下来说操作符的分类:

Creating Observables(创建型操作符)、

Create、Just、Form、DeferEmpty/Never/ThrowIntervalRange、Repeat、Start、Timer,

这里用代码演示:

  public static  void create()
    {
        Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("Create操作符");
                subscriber.onCompleted();
            }
        }).subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {
                System.out.println("onCompleted():");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onCompleted():");
            }

            @Override
            public void onNext(String s) {
                System.out.println("onNext():"+s);
            }
        });
    }

just操作符无非是create的简便写法,

 public static void just()
    {
        Observable.just("just操作符").subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {
                System.out.println("onCompleted():");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError():");
            }

            @Override
            public void onNext(String s) {
                System.out.println("onNext():"+s);
            }
        });
    }

Form操作符是针对数组或者数组列表来操作:

public static void form()
    {

        Observable.from(new Integer[]{1,2,3,4,5,6}).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                System.out.println("onCompleted():");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError():");
            }

            @Override
            public void onNext(Integer s) {
                System.out.println("onNext():"+s);
            }
        });
    }

这里写图片描述

当然也可以是数组列表,结果是一样格式的:

 List datas=new ArrayList();
        for (int i = 0; i <10 ; i++) {
            datas.add(i);
        }
        Observable.from(datas).subscribe(new Subscriber<Integer>() {....}

官方介绍defer是在subscribe调用时才创建observable,

  private static String string;
    public static void defer()
    {
        Observable observable=Observable.defer(new Func0<Observable<String>>() {
            @Override
            public Observable call() {
                return Observable.just(string);
            }
        });
          string="defer操作符";
        observable.subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {
                System.out.println("onCompleted():");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError():");
            }

            @Override
            public void onNext(String s) {
                System.out.println("onNext():"+s);
            }
        });
    }

将会打印出 “defer操作符”;,如果将defer换成just试试。

  private static String string;
    public static void defer()
    {
//        Observable observable=Observable.defer(new Func0<Observable<String>>() {
//            @Override
//            public Observable call() {
//                return Observable.just(string);
//            }
//        });
        Observable observable=Observable.just(string);
        string="defer操作符";
        observable.subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {
                System.out.println("onCompleted():");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError():");
            }

            @Override
            public void onNext(String s) {
                System.out.println("onNext():"+s);
            }
        });
    }
}

这样将打印出null,这是因为在subscribe之前就已经创建好observable对象了,更改值是不管用的。

Empty操作符是创建一个空的observable对象,直接调用oncompleted方法。
Never操作符是不进行发射、回调的方法。
Throw是发送一个错误,执行onerror方法。
Interval操作符就是我们讲的定时器,多长时间操作一次,是有周期性的。
使用interval做周期性操作。当有“每隔xx秒后执行yy操作”类似的需求的时候,想到使用interval

例如:每隔2秒输出日志“helloworld”。

 public static void interval()
    {
        Observable.interval(1, TimeUnit.SECONDS, Schedulers.trampoline()).subscribe(new Subscriber<Long>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Long aLong) {
                System.out.println("onNext():"+aLong);
            }
        });

    }
    //Schedulers.trampoline()这句话不添加,我的是没有效果的。

这里写图片描述

range顾名思义是范围内输出,第一个参数为起始值,第二个为发送的个数,如果为0则不发送,负数则抛异常:,

  public static void range()
    {
        Observable.range(1,5).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer integer) {
                System.out.println("onNext():"+integer);
            }
        });
    }

输出1-5。

repeat是重复操作符。上一个代码中重复执行,将打印1,2,3,4,5,两次。

 public static void range()
    {
        Observable.range(1,5).repeat(2).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer integer) {
                System.out.println("onNext():"+integer);
            }
        });
    }

timer同样是定时发射器,而这个是没有周期性的
使用timer做定时操作。当有“x秒后执行y操作”类似的需求的时候,想到使用timer

例如:2秒后输出日志“hello world”,然后结束。

Observable.timer(2, TimeUnit.SECONDS)  
              .subscribe(new Observer<Long>() {  
                  @Override  
                  public void onCompleted() {  
                      log.d ("completed");  
                  }  

                  @Override  
                  public void onError(Throwable e) {  
                      log.e("error");  
                  }  

                  @Override  
                  public void onNext(Long number) {  
                      log.d ("hello world");  
                  }  
              });  

Transforming Observable(转换型操作符)、

Map、FlatMap、GroupBy、Buffer、Scan、Window。

Map操作符是将一个对象转化成另一个对象。

 public static void map()
    {
        Observable.just(123).map(new Func1<Integer, String>() {
            @Override
            public String call(Integer integer) {
                return integer+"我是转化的String";
            }
        }).subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(String s) {
                System.out.println(s);
            }
        });
    }

将打印出“123我是转化的String”;

FlatMap操作符是一对多的转化对象,例如可以打印一组学生的名字,用from,但是如果再打印每个学生所选的课程呢?这个时候就用flatMap。

Observable.from(students)
    .flatMap(new Func1<Student, Observable<Course>>() {
        @Override
        public Observable<Course> call(Student student) {
            return Observable.from(student.getCourses());
        }
    })
    .subscribe(subscriber);

buffer操作符是将数据指定个数捆绑,捆绑后发送。

 Observable.range(0, 5).buffer(2).subscribe(new Action1<List<Integer>>() {
            @Override
            public void call(List<Integer> integers) {
                System.out.println(integers);
            }
        });

结果:

这里写图片描述

Scan操作符是一个每次将前面的数据进行累计,再按照自定义规则进行运算,依次输出每次计算后的结果给订阅者。

  public static void scan()
    {
        Observable.range(0,5).scan(new Func2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer sum, Integer arg0) {
                return sum+arg0;
            }
        }).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("sum:"+integer);
            }
        });
    }

结果:

这里写图片描述

window操作符会在时间间隔内缓存结果,类似于buffer缓存一个list集合,区别在于window将这个结果集合封装成了observable。

window(long timespan, TimeUnit unit)
第一个是缓存的间隔时间,第二个参数是时间单位

Observable.interval(1,TimeUnit.SECONDS).take(10).window(3,TimeUnit.SECONDS).subscribe(new Observer<Observable<Long>>() {  
            @Override  
            public void onCompleted() {  
                LogUtils.d("------>onCompleted()");  
            }  

            @Override  
            public void onError(Throwable e) {  
                LogUtils.d("------>onError()" + e);  
            }  

            @Override  
            public void onNext(Observable<Long> integerObservable) {  
                LogUtils.d("------->onNext()");  
                integerObservable.subscribe(new Action1<Long>() {  
                    @Override  
                    public void call(Long integer) {  
                        LogUtils.d("------>call():" + integer);  
                    }  
                });  
            }  
        });  

Filtering Observable(过滤型操作符)、

Debounce(超过指定时间才发送)、Distinct(去掉重复)、ElementAt(指定位置的数据)、Filter(按条件过滤)、First(取列表第一位数据)、IgnoreElements(忽略列表上所有元素,只进行onCompleted或者onError方法)、Last(取最后一位数据)、Sample(取样,当到了指定时间采集到数据后才发送)、Skip(跳过几项数据)、SkipLast(跳过数据列表的最后几项)、Take(取前几个数据)、Take(取列表的后几个数据)

Debounce(超过指定时间才发送),每一个数据只有超出指定时间后才会被发送出去,

public static void debounce()
    {
        Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                try {
                    for (int i = 0; i < 10 ; i++) {
                        Thread.sleep(1000*i);
                        subscriber.onNext(i);
                    }
                    subscriber.onCompleted();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).debounce(5,TimeUnit.SECONDS).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println(integer);
            }
        });
    }

打印结果是之前0-4等待时间都没超过5秒,打印结果是5,6,7,8,9;

Distinct(去掉重复)操作符,会自动过滤掉重复的元素。

  public static void  distinct()
    {
        Observable.just(1,2,3,2,1).distinct().subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println(integer);
            }
        });
    }

打印出1,2,3;

ElementAt操作符取出指定位置数据,

 public static void elementAt()
    {
        Observable.just(1,2,3,4,5).elementAt(2).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println(integer);
            }
        });
    }

打印结果3。

Filter过滤操作符。


        Observable.just(1,2,3,5,8).distinct().filter(new Func1<Integer, Boolean>() {
            @Override
            public Boolean call(Integer integer) {
                return integer>2;
            }
        }).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println(integer);
            }
        });

打印结果3,5,8;

带有first和last都不演示了。。很简单。

IgnoreElements忽略数据,直接调用onCompleted或者onError。

public static void IgnoreElement()
    {
        Observable.just(1,2,3,4).ignoreElements().subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                System.out.println("onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError"+e);
            }

            @Override
            public void onNext(Integer integer) {
                System.out.println("onNext"+integer);
            }
        });
    }

打印结果 onCompleted。

Sample操作符是在指定时间内采集数据并发送。

public static void sample()
    {
        Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {

                    try {
                        for (int i = 0; i <10 ; i++) {
                            subscriber.onNext(i);
                            Thread.sleep(1000);
                        }
                        subscriber.onCompleted();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        subscriber.onError(e);
                    }
            }
        }).sample(4,TimeUnit.SECONDS).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println(integer);
            }
        });
    }

打印结果:3,7;

Skip操作符,跳过前几项,输出剩余。

  public static void skip()
    {
        Observable.just(1,2,3,4,5).skip(2).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println(integer);
            }
        });
    }

打印结果:3,4,5

take操作符取前几项数据发送。

 public static void take()
    {
        Observable.just(1,2,3,4,5).take(3).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println(integer);
            }
        });
    }

打印结果:1,2,3

Combining Observables(组合型操作符)、

Zip、Merge、StartWith、CombineLatest、Join、SwitchOnNext

Zip操作符是用来合并两个Observable发射的数据项,根据Function2函数生成一个新的值并发射出去,当其中一个Observable发送数据结束或者出现异常后(两边个数不够,对应不上),另一个observable将停止发射。

public static void zip()
    {
        Observable<Integer> observable1=Observable.just(1,2,3,4);
        Observable<Integer> observable2=Observable.just(5,6,7,8,9);

        Observable.zip(observable1, observable2, new Func2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer integer, Integer integer2) {
                return integer+integer2;
            }
        }).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("next:"+integer);
            }
        });

    }

结果是next:6,next :8,next :10,next :12,因为第一个observable没有数据了所以不能与9结合,终止另一个数据的发射。

merge操作符就是将两个observable按顺序发送数据项进行排列组合,简单说就是将两个observable对象合并成一个observable对象来处理。

 public static void merage()
    {
        Observable<Integer> observable1=Observable.just(1,2,3,4);
        Observable<Integer> observable2=Observable.just(5,6,7,8,9);

        Observable.merge(observable1, observable2).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("merge:"+integer);
            }
        });

    }

结果就是merge:1,merge:2…….merge:9。

StartWith操作符简单点说就是在数据项前面添加新的observable数据项。

  public static void startwith()
    {
        Observable<Integer> observable1=Observable.just(1,2,3,4);
        Observable<Integer> observable2=Observable.just(5,6,7,8,9);

       observable1.startWith(observable2).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("startwith:"+integer);
            }
        });

    }

结果就是StartWith:5,6,7,8,9然后才是1234。

CombineLatest操作符是用于将第一个observable对象最近发射的数据与第二个observable对象进行函数的规则组合。看代码。

 public static void cominelatest()
    {
        Observable<Integer> observable1=Observable.just(1,2,3,4);
        Observable<Integer> observable2=Observable.just(5,6,7,8,9);

        observable1.combineLatest(observable1, observable2, new Func2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer integer, Integer integer2) {
                System.out.println("第一个数据:"+integer+"   第二个数据"+integer2);
                return integer+integer2;
            }
        }).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("两个数据的和:"+integer);
            }
        });

    }

结果:
这里写图片描述

这里意思就是第一个observable对象的4是和第二个observable对象离得最近,所以是4和第二个observable对象发射的数据进行组合,产生新的数据。

join操作符把类似于combineLatest操作符,也是两个Observable产生的结果进行合并,合并的结果组成一个新的Observable,但是join操作符可以控制每个Observable产生结果的生命周期,在每个结果的生命周期内,可以与另一个Observable产生的结果按照一定的规则进行合并。

switchOnNext操作符是把一组Observable转换成一个Observable,转换规则为:对于这组Observable中的每一个Observable所产生的结果,如果在同一个时间内存在两个或多个Observable提交的结果,只取最后一个Observable提交的结果给订阅者。
这里写图片描述

Error Handling Operators(处理错误)。

常用场景:

使用throttleFirst防止按钮重复点击

ps:debounce也能达到同样的效果

RxView.clicks(button)  
              .throttleFirst(1, TimeUnit.SECONDS)  
              .subscribe(new Observer<Object>() {  
                  @Override  
                  public void onCompleted() {  
                        log.d ("completed");  
                  }  

                  @Override  
                  public void onError(Throwable e) {  
                        log.e("error");  
                  }  

                  @Override  
                  public void onNext(Object o) {  
                       log.d("button clicked");  
                  }  
              });  

使用schedulePeriodically做轮询请求

Observable.create(new Observable.OnSubscribe<String>() {  
            @Override  
            public void call(final Subscriber<? super String> observer) {  

                Schedulers.newThread().createWorker()  
                      .schedulePeriodically(new Action0() {  
                          @Override  
                          public void call() {  
                              observer.onNext(doNetworkCallAndGetStringResult());  
                          }  
                      }, INITIAL_DELAY, POLLING_INTERVAL, TimeUnit.MILLISECONDS);  
            }  
        }).subscribe(new Action1<String>() {  
            @Override  
            public void call(String s) {  
                log.d("polling….”));  
            }  
        })  

解决嵌套回调(callback hell)问题

NetworkService.getToken("username", "password")  
    .flatMap(s -> NetworkService.getMessage(s))  
    .subscribe(s -> {  
        System.out.println("message: " + s);  
}) 

响应式的界面

比如勾选了某个checkbox,自动更新对应的preference

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);  
RxSharedPreferences rxPreferences = RxSharedPreferences.create(preferences);  

Preference<Boolean> checked = rxPreferences.getBoolean("checked", true);  

CheckBox checkBox = (CheckBox) findViewById(R.id.cb_test);  
RxCompoundButton.checkedChanges(checkBox)  
        .subscribe(checked.asAction()); 

使用merge合并两个数据源。

例如一组数据来自网络,一组数据来自文件,需要合并两组数据一起展示。

Observable.merge(getDataFromFile(), getDataFromNet())  
              .observeOn(AndroidSchedulers.mainThread())  
              .subscribe(new Subscriber<String>() {  
                  @Override  
                  public void onCompleted() {  
                      log.d("done loading all data");  
                  }  

                  @Override  
                  public void onError(Throwable e) {  
                      log.d("error");  
                  }  

                  @Override  
                  public void onNext(String data) {  
                      log.d("all merged data will pass here one by one!")  
              });  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值