Rxjava学习

  

      所谓的Rxjava可以理解为异步,他的一切操作都是为了异步,是通过一种拓展的观察者模式实现的。所谓观察者模式,像Android开发中的btn.setOnclickListener(this),这种的就是观察者模式。这里的btn就是被观察者,所处的activity或者fragment就是观察者,说白了就是被观察者给自己设置个与观察者有关联的监听器,用于事件触发后通知观察者。

     Rxjava观察者模式

     Rxjava基本概念:Observable (被观察者),Observer(观察者),subscribe (订阅)事件,Observable(被观察者)与Observer(观察者)通过subscribe进行关联,从而Observable在被观察的事件被触发的时候通知Observer;

    Rxjava回调函数里包括:onNext(),onCompleted()和onError();

  onNext():相当于onclick(),做一些回调处理。

  onCompleted():事件队列完结。Rxjava不仅把每个事件单独处理,还把他们看作一个队列。当最后一个onNext()方法执行结束的时候,就会调用

onCompleted();

  onError():事件队列执行异常;在事件执行的过程中出现异常,这个时候触发onError(),同时终止队列,不在允许发布事件,这里要注意一点:

就是onError()和onCompleted()是互斥的,只允许执行一个。

 基本使用

  1、创建Observer 

      Observer即观察者,他决定被观察者通知观察者后需要做什么处理,相当于setOnClickListener;

         Observer<T> observer = new Observer<T>(){

            @Override

             public void onNext(T t){

 

            }

             @Override

             public void onCompleted(T t){

 

            }

           @Override

             public void onError(T t){

 

            }

};

除了observer之外,Rxjava还内置了一个oberver的抽象类:Subscriber,这个是对oberver做了一些扩展,基本使用没有区别。

Subscriber<T> subscriber= new Subscriber<T>(){

            @Override

             public void onNext(T t){

 

            }

             @Override

             public void onCompleted(T t){

 

            }

           @Override

             public void onError(T t){

 

            }

};

而且oberver在被subscribe的过程中,oberver也会常常被转为Subscriber在使用,他们对于开发者的主要区别有两点:

1、onstart(),这个是subscribe扩展方法,在事件还未发出之前做一些准备工作,总是在subscribe所在的线程执行,不能够指定线程,

所以不适合需要在主线程做操作。若要在指定的线程中做一些操作,可以用doOnSubscribe(),这个后面再说。

2、unsubscribe(),这个方法使用来结束事件的发送,也可以理解释放subscribe的引用。在我们不在使用的时候可以在合适的地方(比如onpause)

调用这个方法对Obervable所持有的subscribe的引用进行释放,这样就不会造成内存泄漏。


2、创建 Observable


        Observable即被观察者,Rxjava通过oncreate()进行创建,在里面可以对事件触发规则进行设定。

         

        Observable  observable = Observable.Oncreate(new  Observable.OnSubscribe<T>()){

        @override

        public void call(Subscriber<? super T> subscriber){

subscriber.onNext("Hello");

subscriber.onNext("Hi");

subscriber.onNext("Aloha");

subscriber.onCompleted();

}

     });

   在Observable(被观察者)被订阅的时候,observable被调用,call方法被调用,接着依次执行3次onNext()方法和一次onCompleted()方法。

  Rxjava还提供一些快速创建的方法:

  just(T...):将参数依次发送出去

  Observable observable = Observable.just("Hello","Hi","Aloha");

   等同于上面的。

  from(T[])/from(Iterable<? extends T>):将传入的数组或 Iterable 拆分成具体对象后,依次发送出来。

  String[] words = {"Hello","Hi","Aloha"};

  Observable observable = Observable.from(words);

   同上。


3、Subscribe (订阅)

    有了ObservableObserver后,就可以用Subscribe将他们绑定,这样就可以进行工作了。

    observable.subscribe(obsever);

    这里要说明一点,observable并不是在创建的时候就发送事件,而是在被subscribe绑定后(即subscriber()方法开始执行时)开始事件发送。

   不完整定义的回调

   Action0是Rxjava的一个接口,里面只有一个方法call,此方法是无参数无返回值的。由于onCompleted()方法也是无参数无返回值的,所以可以将Action0包装传入subscribe。

我的理解是:这个就是用Action0替代Subscriber中的onCompleted()方法。

 Action1类似于Action0,不同的是它有一个参数,这样他们就可以用来替代onNext()和onError()。

 Rxjava中提供了多个Actionx接口,比如Action2、Action3,我觉得后面的数字就是它所具有的参数的个数(这一点并没有证实,不过按照设计理念来说应该是这样的)。


 好了,到这里Rxjava的基本使用已经说完了,不过。。这些并没什么ruan用。因为Rxjava的事件发出和消费默认是在同一个线程执行的,这远远的背离了它异步的初衷,

因此,这要说说两一个概念:Scheduler 。

 

   3、线程控制Scheduler 


   Scheduler(线程调度器),说白就是Rxjava中对一段代码指定所要运行的线程。Rxjava中内置了几个Scheduler ,这些已经可以满足大多数的需求了:

   Schedulers.immediate():这是默认的,就是不指定线程,在当前线程中运行。

  Schedulers.newThread():这个是启动一个行线程,在这个新线程中执行

   Schedulers.io():这个和newThread()差不多,不过能不是用一个无数量限制的线程池实现的,可以重用空闲线程,因此要比newThread()更有效率。

但是,不要把在里面进行计算工作,以免建造不必要的线程。

   Schedulers.computation():用于计算的Scheduler.这个CPU计算是指密集型计算,即不会被I/O操作限制性能的,比如图形计算。这个是用一个固定的线程池实现的,

线程数量等于CPU核数,不要把I/O操作放在这里面,否则I/O的等待时间会浪费CPU

  AndroidSchedulers.mainThread():这个是给Android专用的,用于指定到主线程执行。


 Observable.just("1","2")

 .subscribeOn(Scheduler.io())

 .observeOn(AndroidScheculers.mainThread())

 .subscribe(new Action1<Interger>()){

  @override

  public void call(Interger num){

  

   }

});

上面的代码是,被创建的事件由于被subscribeOn()指定,所以事件内容“1”、“2”会在io线程里发送出去。而subscriber 被observeOn()指定,所以call方法会在主线程执行。

这里要说下的是,事件(即被观察者)可以在被创建后用subscribeOn指定线程,但是subscriber(观察者)必须要在被创建之前被observeOn()指定。


4. 变换
     所谓的变换就是对事件或者事件序列进行加工处理,从而得到新的事件或者事件序列。

     map():事件对象的变换

  Observable.just(images/logo.png)

        .map(new Func1<String,Bitmap>(){

          @override

          public Bitmap call(String filePath){

            return getBitmapFromPath(filePath);

           }

         })

        .subscribe(new Action1<Bitmap>(){

          @override

           public void call(Bitmap bitmap){

              showBitmap(bitmap);

            }

        });

Func1和Action1一样也是Rxjava的接口,区别在于Func1有返回值。上面通过map将String类型转换为Bitmap,然后通过subscribe展示。


flatMap():这个比较难理解,举个例子:

 Student[] students = ...;

Subscirber subscriber = new Subscirber<Course>(){

@override

onNext(Course course){

}

};

Observable.from(students)

.flatMap(new Func1<Student,Observable<Course>>(){

@override

observable<Course> call(Student student){

return Observable.from(student.getCourse);

}

})

.subscribe(subscriber);

上面的代码执行过程是这样的,首先创建参数是Student对象的数组,然后开始执行flatMap方法,而这方法对传入的students进行循环的获取,取出Course并创建Observable对象,

这个对象才是与下面的subscriber匹配的。接着将这样Observable对象依次放入同一个Observable中,相当于把一些对象依次存入集合中,然后统一发出去交给subscriber依次处理,

相当于for循环subscriber中call方法。

以上就是我对flatMap()的理解,我所看的文章的作者叫它为铺平,而我觉得叫它整合更好些,将一组Observable对象进行整合后统一发送。

变换的原理:lift()
精简掉细节的话,也可以这么说:在  Observable  执行了  lift(Operator)  方法之后,会返回一个新的  Observable ,这个新的  Observable  会像一个代理一样,负责接收原始的  Observable  发出的事件,并在处理后发送给  Subscriber

就是相当于lift()生成一个新的observable对原始的observable和Subscriber进行关联,在事件触发时,由新observable同志原始observable(如有多层,即上一层),接受原始observable(如有多层,即上一层)处理,然后发送到Subscriber(如有多层,即下一层)。(详细的可以看这篇文章


compose: 对 Observable 整体的变换

     这个是针对 Observable 自身进行变换,我的理解是observable通过N个lift()方法对observable进行转换,最终得到自己想要的处理发送。中间的过程类似于lift()。

5. 线程控制:Scheduler (二)
  subscribeOn()指定的是Observable  和  observeOn()指定的是Subscriber线程,它们的切换线程的原理类似于lift()。
       subscribeOn()可以在任何位置,并且只能执行一次。由于subscribeOn线程切换发生在OnSubscribe 中,也就是说它在通知上级时,而事件并没有发出去,因此subscribeOn线程控制在事件开端就已经有影响了。

     observeOn()由于在内建的(也就是上面说的lift新建的observable对象)Subscriber 进行线程切换,所以它只会对下一个Subscriber 有影响。因此要在Subscriber 发送事件进行设置。


延伸:doOnSubscribe()
   这个类似于 Subscriber.onstart(),都是在 Subscriber执行时,事件并未发出去的时候调用。区别在于 doOnSubscribe()可以指定线程,而onstart()不可以。默认情况下, doOnSubscribe() 执行在 subscribe() 发生的线程;而如果在 doOnSubscribe() 之后有 subscribeOn() 的话,
它将执行在离它最近的 subscribeOn() 所指定的线程。(也就是 doOnSubscribe()下面一个subscribeOn()

RxBinding
     是 Jake Wharton 的一个开源库,它提供了一套在 Android 平台上的基于 RxJava 的 Binding API。所谓 Binding,就是类似设置  OnClickListener  、设置  TextWatcher  这样的注册绑定对象的 API。

RxBus
  类似EventBus,他们之间的选择,是我下面要了解的。

最后

这是我第一次写博客,时间仓促,有很多不足,望见谅。


每天进步一点,量变形成质变。

参考文章:http://gank.io/post/560e15be2dca930e00da1083;






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值