码迷,mamicode.com
首页 > 编程语言 > 详细

RxJava入门七问(一)

时间:2016-07-19 10:50:02      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:

1. RxJava采用了观察者模式,什么是观察者模式呢,能不能举个例子?

答:

小偷(被观察者)把手伸进路人的钱包后(事件),给警察(观察者)发了条短信,曰:快来抓我哟!警察收到信息后,立马采取行动,把小偷按倒在地(行动)
这个小偷是不是很贱,偷东西还要告诉警察

2. 一个语文作业题:分析下面这句话的主、谓、宾 observable.subscribe(observer)

答:
- 主语:observable 被观察者
- 谓语:subscribe 订阅
- 宾语:observer 观察者

题外话:观察者.订阅(被观察者)貌似要更合理些,但对流式 API 的设计就造成影响了,比较起来明显是得不偿失的。

3. 主谓宾找的不错,能不能具体说说主语、谓语、宾语的具体含义

答:

主语:Observable 即被观察者(小偷)
它决定什么时候触发事件(行窃时间)以及触发怎样的事件(是行窃,还是助人为乐)
RxJava 使用 create() 方法来创建一个 Observable ,并为它定义事件触发规则:

   Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("偷穿红上衣的女子");
            subscriber.onNext("偷穿白裤子的男孩");
            subscriber.onNext("偷戴帽子的老头");
            subscriber.onCompleted();//偷完收工
        }
    });

在这里,你创建了observable 之后,其参数OnSubscribe的call方法,并不会马上执行,只有当发生了订阅时(即observable.subscribe(observer))时,才会执行call方法。
你可以理解成这个小偷的确是太贱了,当没有警察盯着他时,他是不会作案的,只有他被警察盯着的时候,他才会作案。

宾语:Observer 即观察者 (警察)
它决定事件触发的时候将有怎样的行为(小偷伸手行窃,并给警察发短信后,警察要采取的动作)
RxJava 中的 Observer 接口的实现方式:

   Observer<String> observer = new Observer<String>() {
        @Override
        public void onNext(String s) {
            //这里的s就上面onNext方法里发送的信息“偷穿红上衣的女子”、"偷穿白裤子的男孩"、"偷戴帽子的老头",会连着输出三次。
            Log.d(tag, "小偷传递来的数据: " + s);
            //"警察采将其按倒在地"也会输出三次
            Log.d(tag, "警察采将其按倒在地");
            //也就是说:小偷每次行窃,警察都会采取行动
        }

        @Override
        public void onCompleted() {
            Log.d(tag, "抓完收工!");
        }

        @Override
        public void onError(Throwable e) {
            Log.d(tag, "oh,no让他给跑了");
        }
    };
  • onCompleted(): 事件队列完结。RxJava 不仅把每个事件单独处理,还会把它们看做一个队列。RxJava 规定,当不会再有新的 onNext() 发出时,需要触发 onCompleted() 方法作为标志。

  • onError(): 事件队列异常。在事件处理过程中出异常时,onError() 会被触发,同时队列自动终止,不允许再有事件发出。

  • 在一个正确运行的事件序列中, onCompleted() 和 onError() 有且只有一个,并且是事件序列中的最后一个。需要注意的是,onCompleted() 和 onError() 二者也是互斥的,即在队列中调用了其中一个,就不应该再调用另一个。

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

    Subscriber<String> subscriber = new Subscriber<String>() {
        @Override
        public void onNext(String s) {
            //这里的s就上面onNext方法里发送的信息“偷穿红上衣的女子”、"偷穿白裤子的男孩"、"偷戴帽子的老头",会连着输出三次。
            Log.d(tag, "小偷传递来的数据: " + s);
            //"警察采将其按倒在地"也会输出三次
            Log.d(tag, "警察采将其按倒在地");
            //也就是说:小偷每次行窃,警察都会采取行动
        }

        @Override
        public void onCompleted() {
              Log.d(tag, "抓完收工!");
        }

        @Override
        public void onError(Throwable e) {
           Log.d(tag, "oh,no让他给跑了");
        }
    };

不仅基本使用方式一样,实质上,在 RxJava 的 subscribe 过程中,Observer 也总是会先被转换成一个 Subscriber 再使用。所以如果你只想使用基本功能,选择 Observer 和 Subscriber 是完全一样的。当然他们也是有区别的,这里就不说了。

跟上文的被观察者类似,这里创建的Observer 或者Subscriber,是不会立即执行其回调方法的,只有当发生了订阅时(即observable.subscribe(observer)或者Observable.subscribe(Subscriber))时,Observer 或者Subscriber的回调方法才会执行

谓语 subscribe()方法 即订阅

创建了 Observable 和 Observer 之后,再用 subscribe() 方法将它们联结起来,整条链子就可以工作了。代码形式很简单:

    observable.subscribe(observer);
    // 或者:
    observable.subscribe(subscriber);

Observable.subscribe(Subscriber) 的内部实现是这样的(仅核心代码):

    // 注意:这不是 subscribe() 的源码,而是将源码中与性能、兼容性、扩展性有关的代码剔除后的核心代码。
    // 如果需要看源码,可以去 RxJava 的 GitHub 仓库下载。
    public Subscription subscribe(Subscriber subscriber) {
        subscriber.onStart();
        onSubscribe.call(subscriber);
        return subscriber;
    }

可以看到,subscriber() 做了3件事:

  1. 调用 Subscriber.onStart() 。这是一个可选的准备方法。
  2. 调用 Observable 中的 OnSubscribe.call(Subscriber) 。在这里,事件发送的逻辑开始运行。从这也可以看出,在 RxJava 中, Observable 并不是在创建的时候就立即开始发送事件,而是在它被订阅的时候,即当 subscribe() 方法执行的时候
  3. 将传入的 Subscriber 作为 Subscription 返回。这是为了方便 unsubscribe().

4. OK,主谓宾解释的还不错,帮我总结一下如何使用最基本的RxJava吧

答:

  1. 创建Observable
  2. 创建Observer或者Subscriber
  3. 订阅:observable.subscribe(observer); 或者 observable.subscribe(subscriber);

5.总结起来虽然就三步,但是具体代码还是很罗嗦,特别是回调方法很多,例如:创建观察者Observer或者Subscriber 时,我只关心onNext()方法,并不关心onComplete()方法和onError()方法, 能不能简化点呢

答:

当然可以
除了 subscribe(Observer) 和 subscribe(Subscriber) ,subscribe() 还支持不完整定义的回调,RxJava 会自动根据定义创建出 Subscriber 。形式如下:

    Action1<String> onNextAction = new Action1<String>() {
        // onNext()
        @Override
        public void call(String s) {
            Log.d(tag, s);
        }
    };
    Action1<Throwable> onErrorAction = new Action1<Throwable>() {
        // onError()
        @Override
        public void call(Throwable throwable) {
            // Error handling
        }
    };
    Action0 onCompletedAction = new Action0() {
        // onCompleted()
        @Override
        public void call() {
            Log.d(tag, "completed");
        }
    };

    // 自动创建 Subscriber ,并使用 onNextAction 来定义 onNext()
    observable.subscribe(onNextAction);
    // 自动创建 Subscriber ,并使用 onNextAction 和 onErrorAction 来定义 onNext() 和 onError()
    observable.subscribe(onNextAction, onErrorAction);
    // 自动创建 Subscriber ,并使用 onNextAction、 onErrorAction 和 onCompletedAction 来定义 onNext()、 onError() 和 onCompleted()
    observable.subscribe(onNextAction, onErrorAction, onCompletedAction);

注意到onNextAction 和onErrorAction的类型是Action1,而onCompletedAction 的类型是Action0 ,有何不同?

目前只要知道:
- Action1的回调方法call需要接收参数
- Action0的回调方法call不需要接收参数就可以了

6.上面只是简化了建观察者Observer或者Subscriber 的回调方法,对于被观察者Observable,有什么简化的方法吗

答:

当然有了

Observable.create() 方法是 RxJava 最基本的创造事件序列的方法。基于这个方法, RxJava 还提供了一些方法用来快捷创建事件队列,例如:

  • just(T…): 将传入的参数依次发送出来。
        Observable observable = Observable.just("Hello", "Hi", "Aloha");
        // 将会依次调用:
        // onNext("Hello");
        // onNext("Hi");
        // onNext("Aloha");
        // onCompleted();
  • from(T[]) : 将传入的数组或 Iterable 拆分成具体对象后,依次发送出来。
String[] words = {"Hello", "Hi", "Aloha"};
            Observable observable = Observable.from(words);
            // 将会依次调用:
            // onNext("Hello");
            // onNext("Hi");
            // onNext("Aloha");
            // onCompleted();

上面 just(T…) 的例子和 from(T[]) 的例子,都和之前的 create(OnSubscribe) 的例子是等价的。

7.那你把最初写的警察抓小偷的例子,用简便方法写一遍

  1. 第一种简便方法—>just
Observable.just("我在偷第一个人","我在偷第二个人","我在偷第三个人").subscribe(new Action1<String>() {
     @Override
     public void call(String s) {
         Log.e("小偷发出的消息",s);
         Log.e("警察","警察采取了行动");
     }
 });
  1. 第二种简便方法—>from
String [] msg={"我在偷第一个人","我在偷第二个人","我在偷第三个人"};
Observable.from(msg).subscribe(new Action1<String>() {
    @Override
    public void call(String s) {
        Log.e("小偷发出的消息",s);
        Log.e("警察","警察采取了行动");
    }
});
下面是log打印
07-17 20:11:35.536 15452-15452/pic.com.rxjavademo E/小偷发出的消息: 我在偷第一个人
07-17 20:11:35.536 15452-15452/pic.com.rxjavademo E/警察: 警察采取了行动
07-17 20:11:35.536 15452-15452/pic.com.rxjavademo E/小偷发出的消息: 我在偷第二个人
07-17 20:11:35.536 15452-15452/pic.com.rxjavademo E/警察: 警察采取了行动
07-17 20:11:35.536 15452-15452/pic.com.rxjavademo E/小偷发出的消息: 我在偷第三个人

怎么样?代码是不是简单多了

未完待续

RxJava入门七问(一)

标签:

原文地址:http://blog.csdn.net/android_study_ok/article/details/51934191

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!