从根上理解RXJava,深入RxJava 的适用场景和使用方式(Retrofit

本文详细介绍了RxJava的核心概念,包括Subscribe、Scheduler、变换和线程控制。通过实例展示了如何使用RxJava处理字符串数组、加载图片等操作,并探讨了与Retrofit的结合。文章强调了异步处理和线程控制的重要性,详细解释了Scheduler的API和原理,以及如何通过compose实现Observable的整体变换。
摘要由CSDN通过智能技术生成

// onNext(“Aloha”);

// onCompleted();

  • from(T[]) / from(Iterable<? extends 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) 的例子是等价的。

3) Subscribe (订阅)

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

observable.subscribe(observer);

// 或者:

observable.subscribe(subscriber);

有人可能会注意到, subscribe() 这个方法有点怪:它看起来是『observalbe 订阅了 observer / subscriber』而不是『observer / subscriber 订阅了 observalbe』,这看起来就像『杂志订阅了读者』一样颠倒了对象关系。这让人读起来有点别扭,不过如果把 API 设计成 observer.subscribe(observable) / subscriber.subscribe(observable) ,虽然更加符合思维逻辑,但对流式 API 的设计就造成影响了,比较起来明显是得不偿失的。

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().

整个过程中对象间的关系如下图:

或者可以看动图:

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

Action1 onNextAction = new Action1() {

// onNext()

@Override

public void call(String s) {

Log.d(tag, s);

}

};

Action1 onErrorAction = new Action1() {

// 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);

简单解释一下这段代码中出现的 Action1 和 Action0。 Action0 是 RxJava 的一个接口,它只有一个方法 call(),这个方法是无参无返回值的;由于 onCompleted() 方法也是无参无返回值的,因此 Action0 可以被当成一个包装对象,将 onCompleted() 的内容打包起来将自己作为一个参数传入 subscribe() 以实现不完整定义的回调。这样其实也可以看做将 onCompleted()方法作为参数传进了 subscribe(),相当于其他某些语言中的『闭包』。 Action1 也是一个接口,它同样只有一个方法 call(T param),这个方法也无返回值,但有一个参数;与 Action0 同理,由于 onNext(T obj) 和 onError(Throwable error) 也是单参数无返回值的,因此 Action1 可以将 onNext(obj) 和 onError(error) 打包起来传入 subscribe() 以实现不完整定义的回调。事实上,虽然 Action0 和 Action1 在 API 中使用最广泛,但 RxJava 是提供了多个 ActionX 形式的接口 (例如 Action2Action3) 的,它们可以被用以包装不同的无返回值的方法。

注:正如前面所提到的,Observer 和 Subscriber 具有相同的角色,而且 Observer 在 subscribe() 过程中最终会被转换成 Subscriber 对象,因此,从这里开始,后面的描述我将用 Subscriber 来代替 Observer ,这样更加严谨。

4) 场景示例

下面举两个例子:

为了把原理用更清晰的方式表述出来,本文中挑选的都是功能尽可能简单的例子,以至于有些示例代码看起来会有『画蛇添足』『明明不用 RxJava 可以更简便地解决问题』的感觉。当你看到这种情况,不要觉得是因为 RxJava 太啰嗦,而是因为在过早的时候举出真实场景的例子并不利于原理的解析,因此我刻意挑选了简单的情景。

a. 打印字符串数组

将字符串数组 names 中的所有字符串依次打印出来:

String[] names = …;

Observable.from(names)

.subscribe(new Action1() {

@Override

public void call(String name) {

Log.d(tag, name);

}

});

b. 由 id 取得图片并显示

由指定的一个 drawable 文件 id drawableRes 取得图片,并显示在 ImageView 中,并在出现异常的时候打印 Toast 报错:

int drawableRes = …;

ImageView imageView = …;

Observable.create(new OnSubscribe() {

@Override

public void call(Subscriber<? super Drawable> subscriber) {

Drawable drawable = getTheme().getDrawable(drawableRes));

subscriber.onNext(drawable);

subscriber.onCompleted();

}

}).subscribe(new Observer() {

@Override

public void onNext(Drawable drawable) {

imageView.setImageDrawable(drawable);

}

@Override

public void onCompleted() {

}

@Override

public void onError(Throwable e) {

Toast.makeText(activity, “Error!”, Toast.LENGTH_SHORT).show();

}

});

正如上面两个例子这样,创建出 Observable 和 Subscriber ,再用 subscribe() 将它们串起来,一次 RxJava 的基本使用就完成了。非常简

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值