Android开发笔记:RxJava学习使用

来源:互联网 发布:java 自己实现线程池 编辑:程序博客网 时间:2024/05/18 00:41

RxJava学习笔记

RxJava是什么

RxJava是在GitHub上一款开源项目。主页介绍为:一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库。是一个基于事件的程序库。

RxJava的作用

RxJava的作用是异步。

RxJava的特点是简洁。可以在逻辑较为复杂的代码中,简洁的异步实现各个逻辑之间的调用。即使需求更改,逻辑越来越复杂,依然能保持代码的简洁性。

实现原理

RxJava的异步实现,是通过观察者模式实现的。

观察者模式

观察者模式是一种依赖关系,是被观察者(Observable)和观察者(Observer/Subscriber)和订阅(Subscribe)的关系。

在RxJava中,Observable(被观察者)和Observer(观察者)之间通过Subscribe()(订阅)方法,产生依赖关系。Observer可以接收Observable发送的数据,Subscriber和Observer相似,实现了Observer对Observer进行了一些拓展。Observer是interface,而Observable是个类。

与传统观察者模式不同, RxJava 的事件回调方法除了普通事件 onNext() 之外,还定义了三个特殊的事件:onComplete() 和 onError(),onSubscribe()。

​ onComplete(): 事件队列完结时调用该方法。RxJava 不仅把每个事件单独处理,还会把它们看做一个队列。
​ onError(): 事件队列异常。在事件处理过程中出异常时,onError() 会被触发,同时队列自动终止,不允许再有事件发出。
​ onSubscribe():RxJava 2.0 中新增的,传递参数为Disposable ,Disposable 相当于RxJava1.x中的Subscription,用于解除订阅。

RxJava流式API调用

代码看下具体的实现,为了使用流式API的调用风格。这里的RxJava订阅关系是,Observable 订阅Observer、

        //流式编译       observable                .just("1","2")                .filter(new Func1<String, Boolean>() {                    @Override                    public Boolean call(String s) {                        return null;                    }                })                .subscribe(new Subscriber(){...});

以上便是流式API调用风格。

基本用法

  • 创建被观察者

         //创建被观察着      Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {          @Override          public void call(Subscriber<? super String> subscriber) {              //做一些数据操作。              //....              // 完成后把结果传给观察者              subscriber.onNext("..");              subscriber.onCompleted();          }      });
  • 创建观察者

        //创建观察者      Observer<String> observer = new Observer<String>() {          @Override          public void onCompleted() {              //被观察者数据操作完成回调          }          @Override          public void onError(Throwable e) {            // 出错回调          }          @Override          public void onNext(String s) {            // 拿到 被观察者数据操作的结果。          }      };
  • 订阅,产生订阅关系。

    // 这里是被观察者订阅观察者。 observable.subscribe(observer);//查看Observable的订阅源码可以看出,是在产生订阅关系时,才调用的call方法,将事件传递出去hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);

Observable的创建方式

  • just();创建方式:

      // just 方式创建的时候,内部已经给自动调用了前边的create()的方式,new 了一个默认的 JustOnSubscribe(){..},在Subscrib的时候自       动调用了,observer的onNext()等方法。//当然just()参数是可变,包含多个参数时,调用create()创建时,new的OnSubScribe是不一样的,这里只写一个参数的做参考。  Observable<T> observable = observable.just(T);// 源码:/** The constant scalar value to emit on request. */  final T t;  protected ScalarSynchronousObservable(final T t) {      super(hook.onCreate(new JustOnSubscribe<T>(t)));      this.t = t;  }
  • from()方式

//from 的方式和just类似,根据参数的不同,会创建不同OnSubscriber,来处理不同的结果给Observer(Subscriber)Observable<String> observable = Observable.from(stringArr);
  • Observable的创建方式还有很多,就不做过多介绍。

RxJava中线程的切换

RxJava在使用的过程中,如果不进行线程的切换,是遵循线程不变的原则,为实现相对于主线程的异步,RxJava使用了Scheduler,线程调度器,来管理线程。

Scheduler(线程调度器)

Scheduler相当于线程切换器,可以通过它,指定RxJava的逻辑是运行在一个什么样的线程中,先来看下RxJava内置的几个调度器:

  • Schedulers.immediate(): 默认的,表示在当前的线程运行。
  • Schedulers.newThread(): 看单词便可以理解,启用新的线程,在新的线程执行操作。
  • Schedulers.io():同样也是开启新的 线程,但是着重于处理一些文件,数据库等读写的操作。
  • Schedulers.computation():计算用到的调度器。
  • AndroidSchedulers.mainThread(): Android用到的主线程。

有了调度器,接下来就是调度器的用法了,在哪里使用,在哪里切换..

Scheduler的用法:

同样的RxJava中调度器的使用也是遵循流式调用的:

        //被观察者的订阅运行在IO线程        observable.subscribeOn(Schedulers.io())                //观察者 在Android主线程运行                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Observer<String>() {                    @Override                    public void onCompleted() {}                    @Override                    public void onError(Throwable e) {}                    @Override                    public void onNext(String s) {}                });

以上调度器的用法是典型的Android中,网络/本地 取数据,主线程更新UI的流程。

RxJava使用操作符进行数据转换

RxJava可以使用map,flatmap方法通过对数据的操作,实现转换得到所需要的数据。举个栗子:

//创建个User类,方便对数据模型操作。class User {        public String id;        public String name;        public List<String> citys;    }
        List<User> userList = ..;        Observable        .from(userList);        .map(new Func1<User, String>() {            @Override            public String call(User user) {                return user.name;//取出name字段。            }        }).subscribe(subscriber);

不用map,直接订阅观察者,就可以打出来,但是这里在表示具体怎么转换的,所以我还是要用下map字段,绕一下,看具体代码怎么使用。现在取的字段是User的name,直接可以拿到,假如取每个User下的存在的city列表,把city都打印出来呢,

  Observable.from(userList)                .map(new Func1<User, List<String>>() {                    @Override                    public List<String> call(User user) {                        return user.citys;                    }                })                .subscribe(new Subscriber<List<String>>() {                    @Override                    public void onCompleted() {                    }                    @Override                    public void onError(Throwable e) {                    }                    @Override                    public void onNext(List<String> strings) {                        //for循环 遍历打印                    }                });

当然以上的方法也是很简单,拿到List的城市信息,直接遍历打印就好,但是RxJava也提供了flatMap的可以更加简单的解决这个问题。

  Observable.from(userList)            .flatMap(new Func1<User, Observable<String>>() {                    @Override                    public Observable<String> call(User user) {                        return Observable.from(user.citys);                    }                })            .subscribe(new Subscriber<String>() {                      @Override                      public void onCompleted() {                      }                      @Override                      public void onError(Throwable e) {                      }                      @Override                      public void onNext(String s) {                          Log.i(TAG, "onNext: "+s);                      }            });

flatMap() 中返回的是个 Observable 对象,并且这个 Observable 对象并不是被直接发送到了 Subscriber 的回调方法中,而是内部进行了转化,统一最终交给了Observer。

算是对RxJava学习使用中的用法的记录。