初识RxJava

来源:互联网 发布:视频音乐提取软件 编辑:程序博客网 时间:2024/06/07 20:37

为什么要用RxJava

因为项目里用到了RxJava,所以最近开始接触它,接触第一天简直是一脸懵逼啊,但是在看了二十几遍“大头鬼Bruce”和“仍物线”的对于RxJava的讲解后,发现RxJava真是太棒了!它其中的链式编程颠覆了我们之前的命令式编程的思想,其最大的好处就是简洁,程序在不断变复杂的情况下,它依然可以保持简洁和很高的可读性。

RxJava是什么

RxJava 的本质可以压缩为异步这一个词。说到根上,它就是一个实现异步操作的库,而别的定语都是基于这之上的。

RxJava的几个基本概念:

  • Observable:被观察者
  • Observer:观察者
  • subscribe:订阅

Observable 和 Observer 通过 subscribe() 方法实现订阅关系,对于初学者来说,刚开始的时候可能和我一样,对于订阅这个词的理解不太到位,慢慢的我觉得它更像是一种关系,类似于绑定、注册等,比如A和B之间通过订阅产生了一种关系。

Hello World

其实,对于初学者来说,写一个RxJava的Hellp World并不难,只需要三步就可以搞定:

  • 一、创建Observable
  • 二、创建Observer
  • 三、将Observable 和 Observer 通过 subscribe() 方法实现订阅关系

下面我们一起来写一下

  1. 创建Observable,创建一个Observable对象很简单,直接调用Observable.create即可
Observable<String> myObservable = Observable.create(      new Observable.OnSubscribe<String>() {          @Override          public void call(Subscriber<? super String> sub) {              sub.onNext("Hello, world!");              sub.onCompleted();          }      }  );

2.这里定义的Observable对象仅仅发出一个Hello World字符串,然后就结束了。接着我们创建一个Subscriber来处理Observable对象发出的字符串。

Observer<String> observer = new Observer<String>() {            @Override            public void onCompleted() {            }            @Override            public void onError(Throwable e) {            }            @Override            public void onNext(String s) {                textView.setText(s);            }        });

3.将Observable 和 Observer 通过 subscribe() 方法实现订阅关系:

myObservable.subscribe(observer);  

OK,大功告成,此时我们就可以输出Hello, world!了。

简化代码

其实上面的代码我们可以简化为一行:

Observable<String> myObservable = Observable.just("Hello, world!");

简单吧!

Subscriber

除了 Observer 接口之外,RxJava 还内置了一个实现了 Observer 的抽象类:Subscriber。 Subscriber 对 Observer 接口进行了一些扩展,但他们的基本使用方式是完全一样的:

Subscriber<String> mySubscriber = new Subscriber<String>() {      @Override      public void onNext(String s) { System.out.println(s); }      @Override      public void onCompleted() { }      @Override      public void onError(Throwable e) { }  }; 

它们的区别对于使用者来说主要有两点:

  1. onStart(): 这是 Subscriber 增加的方法。它会在 subscribe 刚开始,而事件还未发送之前被调用,可以用于做一些准备工作,例如数据的清零或重置。这是一个可选方法,默认情况下它的实现为空。需要注意的是,如果对准备工作的线程有要求(例如弹出一个显示进度的对话框,这必须在主线程执行), onStart() 就不适用了,因为它总是在 subscribe 所发生的线程被调用,而不能指定线程。要在指定的线程来做准备工作,可以使用 doOnSubscribe() 方法,具体可以在后面的文中看到。

  2. unsubscribe(): 这是 Subscriber 所实现的另一个接口 Subscription 的方法,用于取消订阅。在这个方法被调用后,Subscriber 将不再接收事件。一般在这个方法调用前,可以使用 isUnsubscribed() 先判断一下状态。 unsubscribe() 这个方法很重要,因为在 subscribe() 之后, Observable 会持有 Subscriber 的引用,这个引用如果不能及时被释放,将有内存泄露的风险。所以最好保持一个原则:要在不再使用的时候尽快在合适的地方(例如 onPause() onStop() 等方法中)调用 unsubscribe() 来解除引用关系,以避免内存泄露的发生。

    注:以上两段取自http://gank.io/post/560e15be2dca930e00da1083#toc_10

Action的引入

我们看到,上面的代码有时我们可能并不关系OnComplete和OnError,这时我们就可以用到Action1。最后的代码可以写成如下:

Observable.just("Hello, world!")      .subscribe(new Action1<String>() {          @Override          public void call(String s) {                System.out.println(s);          }      }); 

有Action1当然会有Action0,它们的区别主要在与Action1是有参数的,可以替换onNext和OnComplete;而Aciton0是无参的,可以替换OnError

线程控制

因为RxJava 的本质可以压缩为异步,所以在RxJava中,线程的切换必不可少,控制线程的方法有两种:subscribeOn和observeOn。这里我就不细讲了,贴一段用法的代码,具体的区别可以看上面链接的文章.

        Observable.create(new Observable.OnSubscribe<String>() {            @Override            public void call(Subscriber<? super String> subscriber) {                subscriber.onNext("123");                subscriber.onCompleted();            }        }).subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Action1<String>() {                    @Override                    public void call(String s) {                        textView.setText(str);                    }                }, new Action1<Throwable>() {                    @Override                    public void call(Throwable throwable) {                        textView.setText("错误!");                    }                }, new Action0() {                    @Override                    public void call() {                    }                });

初识简单操作符

RxJava之所以灵活多遍,可以适用在很多场景,操作符算是头功。操作符主要解决了对Observable对象的变换的问题,用于在Observable和最终的Subscriber之间修改Observable发出的事件。像上面用到的just,create,它们都属于操作符。常用的操作符还有map、flatmap、concat、zip等等,这里说几个简单的,具体操作符介绍大全可以看这篇文章:http://blog.chinaunix.net/uid-20771867-id-5187376.html 大神写的非常非常全。

map

首先看一段代码:

Observable.just("a")                .map(new Func1<String, Integer>() {                    @Override                    public Integer call(String s) {                        return s.hashCode();                    }                })                .subscribe(new Action1<Integer>() {                    @Override                    public void call(Integer s) {                        System.out.print(Integer.toString(s));                    }                });

你猜的没错,最后的输出结果为a的hashCode码97。所以,我们可以想到,map()的作用为:
用于变换Observable对象,map操作符返回一个Observable对象,这样就可以实现链式调用,在一个Observable对象上多次使用map操作符,最终将最简洁的数据传递给Subscriber对象。

first

同样的,我们再看一段代码:

        Observable.just(1,2,3,4,5,6,7,8)          .first()          .subscribe(new Subscriber<Integer>() {              @Override              public void onNext(Integer item) {                  System.out.println("Next: " + item);              }              @Override              public void onError(Throwable error) {                  System.err.println("Error: " + error.getMessage());              }              @Override              public void onCompleted() {                  System.out.println("Sequence complete.");              }          });

输出结果为:

Next: 1Sequence complete.

因此,first的作用为:first操作符是把源Observable产生的结果的第一个提交给订阅者,注意:这里的第一个并不一定是数字上的第一个,而是符合输出条件的第一个,看一下下面的例子:

Observable.create(new Observable.OnSubscribe<Integer>() {            @Override            public void call(Subscriber<? super Integer> subscriber) {                subscriber.onNext(1);                subscriber.onNext(2);                subscriber.onNext(3);                subscriber.onCompleted();            }        }).first(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.print(integer);            }        });

这个例子最终的输出结果为3,这下明白了吧。好了,操作符合就暂时举这两个例子,更多的大家可以看上面的链接,以后我有时间的话会专门再写一篇操作符的文章。

好了,这就是我对RxJava的初步理解,有写的不好的地方请大家多多指教。最后附上一个我自己写的很简单的demo,代码很简单,但是对于初学者来说都是很经典的东西:
http://download.csdn.net/detail/dzx997681136/9654805

“大头鬼Bruce”和“仍物线”两位大神的RxJava的介绍给了我很大的帮助,附上两篇文章的链接:
http://gank.io/post/560e15be2dca930e00da1083#toc_10
http://blog.csdn.net/lzyzsd/article/details/41833541/

1 0
原创粉丝点击