RxJava使用及原理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jinhuoxingkong/article/details/75050750

一、概念



什么是RxJava

RxJava主要是用来进行异步操作的,其和其他异步方式如Asytask还有Handler的实现方式是不同的,线性的编程结构使得程序更加清晰



二、标准格式


被观察者的标准格式

        //创建被观察者,这是最正常的创建方法
        Observable observable=Observable.create(new Observable.OnSubscribe<String>(){

            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("一二三四五");
                subscriber.onNext("上山打老虎");
                subscriber.onNext("老虎一发威");
                subscriber.onNext("武松就发怵");
                subscriber.onCompleted();
            }
        });
也可以使用just和from的方式来进行偷懒,也就是简洁化的方式


如下是观察者的标准格式

        Subscriber subscriber=new Subscriber<String>() {
            @Override
            public void onCompleted() {
                mText.append("执行观察者中的onCompleted()...\n");
                mText.append("订阅完毕,结束观察...\n");
            }

            @Override
            public void onError(Throwable e) {

            }
            @Override
            public void onNext(String s) {
                mText.append("执行观察者中的onNext()...\n");
                mText.append(s+"...\n");
            }

        };

最后将观察者和被观察者进行订阅

observable.subscribe(subscriber);


三、RxJava原理


首先提出三个问题

  • 被观察者中的Observable.OnSubscribe是什么,有什么用?
  • call(subscriber)方法中,subscriber哪里来的?
  • 为什么只有在订阅之后,被观察者才会开始发送消息?

(1)第一个问题:OnSubscribe本质上也是和 Action1一样的接口,内部也是会调用call函数的

而在Observable观察者的类中,OnSubscribe是它唯一的属性,同时也是Observable构造函数中唯一必须传入的参数,也就是说,只

要创建了Observable,那么内部也一定有一个OnSubscribe对象。

(2)第二个问题:call(Subscriber<? super String> subscriber)中的subscriber,就是我们自己创建的那个观察者,这里将观察者传递进去,我们就可以调用观察者的onNext方法了。

(3)第三个问题:只有在订阅的时候,才会发生onSubscribe.call(subscriber),进而才会开始调用onNext(),onComplete()等。也就是说只有当我们订阅的时候才是调用的开始,这个过程就理清了。


  • 订阅这个动作,实际上是观察者(subscriber)对象把自己传递给被观察者(observable)内部的onSubscribe
  • onSubscribe的工作就是调用call(subscriber)来通知被观察者发送消息给这个subscriber


四、操作符



其实RxJava中最重要的操作符,它可以在订阅的过程中进行各种转化,下面以Map操作符为例子来进行说明,Map操作符本身就是一个映射的关系

        mText.append("\n 输入参数: 1,2,3,4,5,6 \n");
        Observable.from(number)           //之前提到的创建Observable方法
                  .map(new Func1<Integer, Boolean>() {
                      @Override
                      public Boolean call(Integer integer) {
                          mText.append("\n\n map()  Integer--->Boolean");
                          return (integer<3);
                      }
                  })
                  .subscribe(new Action1<Boolean>() {
                    @Override
                    public void call(Boolean aBoolean) {
                        mText.append("\n观察到输出结果:\n");
                        mText.append(aBoolean.toString());

                    }
                });
这里的Map进行了类型的转换,将int转变成嗯boolean类型的


五、操作符原理



(1)首先创建一个代理的观察者

(2)让外部的Obervable去订阅这个代理的观察者

(3)外部的观察者发送onNext等事件,都会先传递到代理观察者这里

(4)在代理观察者的onNext中调用自己创建的Fun1的call方法,进行数据的转化

(5)当我们在调用obervable的call方法的时候会将真实的观察者传递进来

(6)调用真实观察者的onNext方法将结果传递出去就可以了




六、线程调度操作符


这个是异步的关键,用来在主线程和子线程之间进行切换

        Observable.create(new Observable.OnSubscribe<Drawable>(){

            @Override
            public void call(Subscriber<? super Drawable> subscriber) {
                sb.append(" Observable.create(): 线程: "+Thread.currentThread().getName()+"\n\n");
                Drawable dd=getResources().getDrawable(R.mipmap.gril);
                subscriber.onNext(dd);
                subscriber.onCompleted();
            }
        }).subscribeOn(Schedulers.io())
          .observeOn(Schedulers.newThread())
          .map(new Func1<Drawable, ImageView>() {
              @Override
              public ImageView call(Drawable drawable) {
                  sb.append("map():  drawable -->imageview 的线程: "+Thread.currentThread().getName()+"\n\n");
                  ImageView img=new ImageView(RxSchuderActivity.this);
                  LinearLayout.LayoutParams params= new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                  img.setLayoutParams(params);
                  img.setImageDrawable(drawable);
                  return img;
              }
          }).observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<ImageView>() {
                @Override
                public void call(ImageView imageView) {
                    sb.append("call(): 线程: "+Thread.currentThread().getName()+"\n");
                    mText.setText(sb);
                    mLinearlayout.addView(imageView);

                }
            });

实际上线程调度只有subscribeOn()和observeOn()两个方法。对于初学者,只需要掌握两点:

  • subscribeOn()它指示Observable在一个指定的调度器上创建(只作用于被观察者创建阶段)。只能指定一次,如果指定多次则以第一次为准

  • observeOn()指定在事件传递(加工变换)和最终被处理(观察者)的发生在哪一个调度器。可指定多次,每次指定完都在下一步生效。

线程调度掌握到这个程度,在入门阶段时绝对够用的了。







尊重作者,尊重原创,参考文章:

http://www.jianshu.com/p/6fd8640046f1

http://www.jianshu.com/p/e61e1307e538

这两篇文章写的非常的好,非常适合入门RxJava




阅读更多
换一批

没有更多推荐了,返回首页