RxJava学习笔记

作者: 某昆 | 来源:发表于2016-07-24 00:45 被阅读221次

    RxJava是目前非常流行的一个框架,通过监听者模式,可快速、方便、且代码通俗易懂地实现很多功能,代码非常优雅。它还有个非常大的好处,就是可以随意切换线程

    • 基础概念

    RxJava最核心的两个东西是Observables(被观察者,事件源)和Subscribers(观察者)。Observables发出一系列事件,Subscribers处理这些事件。这里的事件可以是任何你感兴趣的东西(触摸事件,web接口调用返回的数据。。。)

    一个Observable可以发出零个或者多个事件,知道结束或者出错。每发出一个事件,就会调用它的Subscriber的onNext方法,最后调用Subscriber.onNext()或者Subscriber.onError()结束。

    Rxjava的看起来很想设计模式中的观察者模式,但是有一点明显不同,那就是如果一个Observerble没有任何的的Subscriber,那么这个Observable是不会发出任何事件的。

    • 基础用法
    Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("hello");
            subscriber.onNext("world");
            subscriber.onCompleted();
    }});
    
    Subscriber<String> subscriber = new Subscriber<String>() {
        @Override
        public void onCompleted() {
            Log.i(TAG,"completed");
        }
        @Override
        public void onError(Throwable e) {
            Log.i(TAG,"onError");
        }
        @Override
        public void onNext(String s) {
            Log.i(TAG,"s = " + s);
        }};
    observable.subscribe(subscriber);
    
    • 进阶用法

    初看代码,RxJava代码好复杂,一点也不优雅,代码量较大,事实上RxJava推崇的是链式调用,为了达到这个目的RxJava作了许多改进,添加了很多人性化的接口。

    Observable的from方法,以及just方法,直接就能生成Observable且将数据传递给订阅者,不需要通过create了,也不需要再写冗长的OnSubscribe了。

    Subscriber,有点类似于java中线程,当我们向线程池中提交一个任务给线程池,并不需要向线程池中提交一个Thread,只需要提交一个Runnable即可。那么,关于Subscriber,我们可以使用Action代码,Action的类有多个,根据需求选择。

    Observable.just("tom","green")
            .subscribe(new Action1<String>() {
                @Override
                public void call(String s) {
                    Log.i(TAG," just s = " + s);
                } 
           });
    

    上述代码可成功实现第一个例子的功能,但代码量非常小,看起来非常舒服。

    • 变换

    变换是RxJava非常犀利的功能,也是RxJava中非常难以理解的一项内容。常见的变换操作符常有map,flatmap等。

    Observable向Subscriber发送数据,供Subscriber使用处理,如果Subscriber想要的数据并不是Observable发送的,这时就需要使用变换了。比如说,加载网络图片时,Observable可以向Subscriber传递一个网络地址,Subscriber自己读取网络地址上的图片。但是RxJava中极少看到这类写法,因为RxJava推崇的是链式调用,最好能直接将Bitmap传给Subscriber。此时变换就可大展身手了。

    变换最重要的作用就是将数据源变成订阅者想要的数据,以符合链式调用原则。

    Observable.just("tom","green")
            .map(new Func1<String, Integer>() {
                @Override
                public Integer call(String s) {
                    return 0;
                }
            })
            .subscribe(new Action1<Integer>() {
                @Override
                public void call(Integer s) {
                    Log.i(TAG," just s = " + s);
                } 
           });
    

    上例中通过map变换将String类型的数据源变换成Integer类型的数据源。map方法,将Observable变成另外一个Observable,向自己的订阅者传递新的类型的数据。

    ps:所有的泛型中都不能使用基础数据类型,int之类的不能使用,否则会报错。

    flatmap和map类似,它的功能则是将一个Observable变成许多个Observable,想象一个场景,打印当前文件夹下所有文件的名字,此时则可以使用flatmap了,通过flatmap将文件夹路径下所有的文件列出来,将文件名传给订阅者,具体代码,读者可以尝试实现下。

    • 线程切换

    RxJava神奇的地方,还在于可以非常方便地切换线程,比如可以将耗时的操作放在工作线程中完成,更新UI的部分则放在主线程中完成,只需要一行代码即可,非常地方便。

    1. subscribeOn
      它用于指定Observable处理数据时所在的线程
    2. observeOn
      它用于指定订阅者处理Observable发送过来的数据时所在的线程

    非常重要的一点,RxJava中遵循链式调用法则,那么它的代码顺序非常重要,虽然以上两个方法分别指定不同过程的线程,但也不能随便写,只有在对应的时刻写以上两个方法,才有效果。

    具体来说,subscribeOn中指定的是耗时工作完成的线程,这类耗时工作常在变换过程当中,比如map之类。而observeOn方法中常用于指定在主线程内更新UI的内容。它们的调用时机一定要把握好,不能随意都写,否则会无效。

    Observable.just(res)
            .subscribeOn(Schedulers.io())
            .map(new Func1<String, Bitmap>() {
                @Override
                public Bitmap call(String s) {
                    Log.i(TAG,"func1 s = " + s + "  t.name = " + Thread.currentThread().getName());
                    return getBitmap(s);
                }
            })
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<Bitmap>() {
                @Override
                public void call(Bitmap bitmap) {
                    Log.i(TAG,"action  "  + "  t.name = " + Thread.currentThread().getName());
                    mImg.setImageBitmap(bitmap);
                }
            });
    

    RxJava中的内容还非常地多,本人记录的只是基础知识,具体的原理、开源代码走读待日后完成,更多地变换内容日后添加,有问题欢迎留言讨论。

    邮箱:okunu@qq.com

    相关文章

      网友评论

        本文标题:RxJava学习笔记

        本文链接:https://www.haomeiwen.com/subject/gpvwjttx.html