RxJava的使用基础教学 一


反应性代码的最基本单元是被观察对象和订阅者。一个被观察对象放出数据,一个订阅者消费这些数据。关于数据的释放有一种模式。一个被观察对象可能释放任意个数的数据(包括零个),然后它会在成功完成后终止,或者由于遇到错误而终止。对每个订阅者,被观察对象会调用Subscriber.onNext()很多次,然后调用Subscriber.onComplete()或Subscriber.onError()。
这看上去非常像标准的观察者模式,但它有一个关键的不同--被观察对象在没有被显式订阅之前是不会开始释放数据的。换句话说:如果没有人在收听,它是不会说话的。

一 被观察者和订阅者

现在来看一个例子,创建了一个基本的被观察对象:

Observable<String> myObservable = Observable.create(
    new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> sub) {
            sub.onNext("Hello, world!");
            sub.onCompleted();
        }
    }
);
这里myObservable释放了一个“Hello, world!”的字符串,接下来需要创建一个订阅者来消费这个字符串:
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) { }
};
这样就可以打印出每个释放出来的字符串了。最后我们只需要将这两者连接起来:
myObservable.subscribe(mySubscriber);
// 输出结果 "Hello, world!"

以上就是标准的使用模板了。但这个例子中很多代码都可以更加简化。

首先,Observable可以得到简化:
Observable<String> myObservable = Observable.just("Hello, world!");
这里的Observable.just()只会释放一条数据,然后完成终止。
然后,在这个例子中我们并不关心onCompleted()和onError(),代替的作法就是使用一个简单的类来定义在onNext()里做什么:
Action1<String> onNextAction = new Action1<String>() {
    @Override
    public void call(String s) {
        System.out.println(s);
    }
};

Action可以定义Subscriber的每个回调。Observable.subscribe()的参数可以有一、二、三个,去代替onNext()、onError()和 onComplete(),就像这样:
myObservable.subscribe(onNextAction, onErrorAction, onCompleteAction);

而在这个例子中我们只关心onNext(),因此只需要:
myObservable.subscribe(onNextAction);
// 输出 "Hello, world!"

这些代码放在一起就变成了:
Observable.just("Hello, world!")
    .subscribe(new Action1<String>() {
        @Override
        public void call(String s) {
              System.out.println(s);
        }
    });


二 操作者
假如我们需要在字符串后面加上一个字符串作为个人标记,可以如下修改:
Observable.just("Hello, world! - Dan")
    .subscribe(new Action1<String>() {
        @Override
        public void call(String s) {
              System.out.println(s);
        }
    });
此处是修改的被观察者,但如果我在很多地方都用到了这个观察者,但只是有时才会加上这段字符串该怎么做呢?
Observable.just("Hello, world!")
    .subscribe(new Action1<String>() {
        @Override
        public void call(String s) {
              System.out.println(s + "-Dan");
        }
    });
此处是修改的订阅者,但有时候订阅者是运行在主线程里,不适合做类似的操作,从概念上说,订阅者应当对事件作出反应,而不是变化。如果我可以在某个中间步骤对这个字符串作处理呢?这里就轮到Operators操作符出场了,它是在观察者和最终订阅者之间被用来操

作被释放的数据。
这里使用map在原字符串结尾加上该字符串:

Observable.just("Hello, world!")
    .map(new Func1<String, String>() {
        @Override
        public String call(String s) {
            return s + " -Dan";
        }
    })
    .subscribe(s -> System.out.println(s));
这里需要注意的一点是,Func1<String, String>尖括号内的参数,第一个String代表传入该map的对象类型是字符类型,第二个String代表从map传出的,即回调call的返回值类型也是字符类型。从这里其实就可以看出来,我们可以对传入的数据进行类型的转换,比如

String到integer:
Observable.just("Hello, world!")
    .map(new Func1<String, Integer>() {
        @Override
        public Integer call(String s) {
            return s.hashCode();
        }
    })
    .subscribe(i -> System.out.println(Integer.toString(i)));
可以看到数据到订阅者那里时已经变成了Integer类型了,更需要说明的一点是自定义model类型的对象也是可以通过它来进行转换的。



需要注意的点:
1 最小的单元实际上是Oberver观察者,但实际使用当中使用得最多的是Subscriber订阅者,因为需要通过它连接被观察者对象。
2 虽然这一点的理解影响并不大但还是需要了解,即热被观察者和冷被观察者,热被观察者指无论是否有订阅者都会释放数据,相对的冷被观察者如先前所说那样,如果没有订阅者它是不会开始释放数据的。

你可能感兴趣的:(RxJava的使用基础教学 一)