RXANDROID学习笔记

RXANDROID学习笔记

RXANDROID

○ 介绍
○ 优势
○ 使用流程
○ 简单实例
○ RX简单符号操作

介绍

Rx(Reactive Extensions)是一个库,用来处理事件和异步任务,在很多语言上都有实现,RxJava是Rx在Java上的实现。简单来说,RxJava就是处理异步的一个库,最基本是基于观察者模式来实现的。通过Obserable和Observer的机制,实现所谓响应式的编程体验

优势

最概括的两个字:简洁。而且当业务越繁琐越复杂时这一点就越显出优势——它能够保持简洁。

使用流程

 配置buile.gradle:(以下为当前最新版本,如有更新请到上述GitHub链接查看更新)
 
dependencies {
  compile ‘io.reactivex:rxandroid:1.2.1’
  compile ‘io.reactivex:rxjava:1.1.6’
  }
  
配置完之后就可以使用RxJava的API了。

介绍两个个关键的类:

  (1)Observable
   
 (2)Subscriber 即:被观察者(Observable)和观察者(Subscriber),其实我觉得叫发布者和订阅者更好理解一些,但大家都叫被观察者和观察者。
 

主干的使用过程就是

  1. 创建被观察者。

    1. 创建观察者。
    2. 将二者建立联系。

      最后然后被观察中发出信息触发观察者的动作,执行相应的方法,

简单实例

    Observable observable = Observable.create(new Observable.OnSubscribe<Integer>() {
        @Override
        public void call(Subscriber<? super Integer> subscriber) {          
        subscriber.onNext(1001);           subscriber.onNext(1002);            subscriber.onNext(1003);            subscriber.onCompleted();
        }
    });
    //创建一个观察者
    Subscriber<Integer> subscriber = new Subscriber<Integer>() {
        @Override
        public void onCompleted() {
            Log.d(TAG, "onCompleted.. ");
        }
        @Override
        public void onError(Throwable e) {
            Log.d(TAG, "subscriber onError.. " + e.getMessage());
        }
        @Override
        public void onNext(Integer integer) {
            Log.d(TAG, "onNext.. integer:" + integer);
        }
    };
    //注册观察者(这个方法名看起来有点怪,还不如写成regisiterSubscriber(..)或者干脆addSubscriber(..))
    //注册后就会开始调用call()中的观察者执行的方法 onNext() onCompleted()等 observable.subscribe(subscriber);

当Observable发射数据时,会依次调用Subscriber的onNext()方法,将发射的数据作为参数传给onNext(),如果出错,则会调用Subscriber的onError()方法,完成所有数据发射后,调用onCompleted()方法,整个过程完毕。
  但是,subcribe()方法默认在当前线程被调用。所以,这样使用的话,被观察者和观察者的所有的动作都是在同一个线程完成的,没卵用…
  但是当然肯定不会就这个程度了,RxJava有两个方法可以很方便的指定观察者和被观察者代码运行的线程,RxAndroid还有一个扩展,可以指定在UI线程运行。
//设置观察者和发布者代码所要运行的线程后

注册观察者

    observable.subscribeOn(Schedulers.immediate())//在当前线程执行subscribe()方法
    .observeOn(AndroidSchedulers.mainThread())//在UI线程执行观察者的方法
    .subscribe(subscriber);

通过Scheduler作为参数来指定代码运行的线程,非常方便,好用到不行…其他常用的参数还有:

 Schedulers.immediate(): 直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。  Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。

Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免建不必要的线程。

Schedulers.computation(): 计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。

另外, Android 还有一个专用的 AndroidSchedulers.mainThread(),它指定的操作将在 Android 主线程运行。
  
  
 
  

RX简单符号操作

使用map()方法做转换:

    Runnable run = new Runnable() {
 @Override
 public void run() {
     //将文件路径转换为bitmap发出 观察者直接收到bitmap进行处理
     Observable observable = Observable.just(imgFilePath);
     observable.map(new Func1<String, Bitmap>() {
         @Override
         public Bitmap call(String imgFilePath) {
             return getBitmapFromAssets(imgFilePath);
         }
     }).subscribeOn(Schedulers.immediate())//当前线程(子线程)发布
             .observeOn(AndroidSchedulers.mainThread())//UI线程执行(更新图片)
             .subscribe(new Subscriber<Bitmap>() {
                 @Override
                 public void onCompleted() {
                     Log.i(TAG, "observable.map(..)  onCompleted");
                 }

                 @Override
                 public void onError(Throwable e) {
                     Log.i(TAG, "observable.map(..)  onError" + e.getMessage());
                 }

                 @Override
                 public void onNext(Bitmap bitmap) {
                     //显示图片
                     iv.setImageBitmap(bitmap);
                 }
             });
 }
    };
    new Thread(run).start();

flatMap()实现双重变换

flatMap()将一个发射数据的Observable变换为多个Observables,然后将它们发射的数据合并后放进一个单独的Observable。即:第一次转换时,它依次将输入的数据转换成一个Observable,然后将这些Observable发射的数据集中到一个Observable里依次发射出来

    Subscriber subscriber = new Subscriber<Integer>() {
@Override
public void onCompleted() {     Log.i(TAG,"Observable.just(array1,array2).flatMap  onCompleted\n\n");
}
@Override
public void onError(Throwable e) {
    Log.e(TAG,"Observable.just(array1,array2).flatMap   onError  "+e.getMessage());
}
@Override
public void onNext(Integer integer) {  Log.d(TAG,"Observable.just(array1,array2).flatMap  integer = "+integer);
}
    }    
    Integer[] array1 = {1, 2, 3, 4}, array2 = {5, 6, 7, 8};
    Observable.just(array1,array2).flatMap(new Func1<Integer[], Observable<?>>() {
      @Override
     public Observable<?> call(Integer[] ints) {
    Observable observable = Observable.from(ints);
    return observable;
     }
    }).subscribe(subscriber);

scan()变换

scan操作符对原始Observable发射的第一项数据应用一个函数,然后将那个函数的结果作为自己的第一项数据发射。它将函数的结果同第二项数据一起填充给这个函数来产生它自己的第二项数据。它持续进行这个过程来产生剩余的数据序列。

    Observable.just(1, 2, 3, 4).scan(new Func2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer integer, Integer integer2) {
    //integer是第一个元素或上一次计算的结果,integer2是下一轮运算中新的序列中元素
    Log.d(TAG, "scan call   integer:" + integer + "   integer2:" + integer2);
    return integer + integer2;
}
    }).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
    Log.i(TAG, "Observable.just(1,2,3,4).scan   onCompleted..");
    initViewState();
}

      @Override
    public void onError(Throwable e) {
    Log.e(TAG, "Observable.just(1,2,3,4).scan  onError  " + e.getMessage());
}

@Override
public void onNext(Integer integer) {
    Log.d(TAG, "Observable.just(1,2,3,4).scan  onNext()..  integer = " + integer);
    /**
     * 第一次为1,然后是3(1+2),6(3+3),10(6+4)
     */
}
    });

作者:施彬彬:原文地址

你可能感兴趣的:(java)