hi,好久不见。
emem,是的,貌似已经很久很久没有更新博客了,之前一直没有在CSDN写博客的习惯,零零散散的用一些笔记工具(印象笔记和typora工具)去写,没有成体系,也没有逼迫自己进行输出倒逼输入,缺乏了持续的思考和记忆,在未来的学习过程中,我将会不断的将自己学习的东西以及一些思考整理和分享出来,大家一起学习,不断提高。
-----------------------------------------------------------------正式开启下文-------------------------------------------------------------
RxJava2 学习教程(一)hello world
今天我们学习的内容是RxJava,之前用过AsyncTask的小伙伴们对异步一定不陌生, RxJava 在Android中是一个比较热门的异步框架,接下来我们将开启学习Rxjava的学习之旅。
这是关于 RxJava 的第一篇文章,今天主要介绍 RxJava2的使用以及基本知识。
- 使用:如何发射和接收事件
- 基本知识:原理及重要 API
1. 关于 RxJava
- RxJava 是Reactive Extensions 的 Java 实现,用于通过使用 Observable/Flowable 序列来构建异步和基于事件的程序的库。
- RxJava 扩展观察者模式以支持数据/事件序列,并添加允许你以声明方式组合序列的操作符,同时提取对低优先级的线程,同步,线程安全性和并发数据结构等问题的隐藏。
- 对于 RxJava,应用十分广泛,任何地方,包括 App 所依赖的底层框架,对于 Android 中的 AsyncTask,也完全可以使用 RxJava 来代替,当然,不仅仅是 Android APP 的开发,在服务器端领域中也经常使用 RxJava。今天我们将一起 走进 RxJava 的学习之旅。
2.RxJava 的使用
2.1 添加配置
我们要在 Android 中使用 RxJava2, 先在app的 build.gradle 文件中添加如下配置:
// Rxjava
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.9'
2.2 RxJava2中的 hello world
原理简介:RxJava 基于观察者模式,通过被观察者发射数据,观察者接收数据,在这里我们用两根水管代替观察者和被观察者,事件产生的水管我们叫它上游,接收事件的水管我们叫它下游。
- 创建 Observable(上游)
Observable 它决定了什么时候去触发事件,在这里可以决定异步操作模块的顺序以及次数。
- 创建 Observer(下游)
Observer 可以在不同的线程中执行任务,是一个处于待命状态的观察者哨兵,用来响应某个时刻 Observable 的通知,不需要阻塞的等待 Observable 发射数据。
- 使用 subscribe() 进行订阅
subscribe() 方法是用于将之前创建的 Observable 以及 Observer连接起来,这样整个上下游就能衔接起来实现链式调用。
具体实现代码如下:
// 创建Observable
Observable<String> mObservable =Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) {
emitter.onNext("hello world");
}
});
// 创建 observer
Observer<String> mObserver=new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
};
// subscribe() 调用
mObservable.subscribe(mObserver);
- 简化版如下:
Observable.just("hello world").subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, "accept: "+s);
}
});
- 链式调用(开发中我们经常使用的是链式调用)
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "onNext:我方已成功发送 "+1);
emitter.onNext(1);
Log.d(TAG, "onNext:我方已成功发送 "+2);
emitter.onNext(2);
Log.d(TAG, "onNext:我方已成功发送 "+3);
emitter.onNext(3);
Log.d(TAG, "onNext:我方已成功发送 "+4);
emitter.onNext(4);
Log.d(TAG, "onNext:我方已成功发送 "+5);
emitter.onNext(5);
Log.d(TAG, "发送完毕! ");
emitter.onComplete();
}
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "我方已成功接收:"+integer;
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
Log.d(TAG, "onNext: "+s);
Log.d(TAG, "........................... ");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.d(TAG, "接收完毕! ");
Log.d(TAG, "........................... ");
}
});
程序运行结果如下:
以上代码很简单,接下来我们主要讲解设计到的技术点以及重要的 API.
(1) ObservableEmitter:
可以理解为发射器,用它进行事件的发射,它可以发射三种类型的事件,调用emitter的onNext(T value)
、onComplete()
和onError(Throwable error)
就可以分别发出next事件、complete事件和error事件。
-
发射规则:
- 上游可以发送无限个onNext, 下游也可以接收无限个onNext.
- 当上游发送了一个onComplete后, 上游onComplete之后的事件将会
继续
发送, 而下游收到onComplete事件之后将不再继续
接收事件. - 当上游发送了一个onError后, 上游onError之后的事件将
继续
发送, 而下游收到onError事件之后将不再继续
接收事件.上游可以不发送onComplete或onError. - onComplete和onError必须唯一并且互斥, 即不能发多个onComplete, 也不能发多个onError, 也不能先发一个onComplete, 然后再发一个onError, 反之亦然
-
事件的调用顺序:
onSubscribe->onNext->onComplete
(2)Disposable:
它的中文意思是一次性的,可自由支配的,在 RxJava 中我们可以将它理解为控制上游 observable 和下游observer之间数据传输的枢纽,或者说开关,我们可以 在某个时刻调用 Disposable 的 dispose() 进行关闭,这样上游可以继续事件的发射,但是下游一旦触发 dispose() 将不再接收事件。
示例代码如下:
Observable<String> mObservable =Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) {
emitter.onNext("kotlin");
Log.d(TAG, "subscribe:kotlin ");
emitter.onNext("Java");
Log.d(TAG, "subscribe: Java");
emitter.onNext("C++");
Log.d(TAG, "subscribe: C++");
emitter.onNext("Python");
Log.d(TAG, "subscribe: Python");
emitter.onNext("go");
Log.d(TAG, "subscribe: go");
}
});
Observer<String> mObserver=new Observer<String>() {
private Disposable mDisposable;
private int i;
@Override
public void onSubscribe(Disposable d) {
mDisposable = d;
}
@Override
public void onNext(String s) {
Log.d(TAG, "onNext: "+s);
i++;
if (i==2){
mDisposable.dispose();
Log.d(TAG, "onNext: 下游已关闭,将不再接收任何数据");
}
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
};
mObservable.subscribeOn(Schedulers.newThread()) //上游线程
.observeOn(AndroidSchedulers.mainThread()) // 下游线程
.subscribe(mObserver);
运行结果如下:
11-27 01:41:19.692 30223-30293/com.example.dolphkon.hellokotlin D/HelloRxjavaActivity: subscribe:kotlin
subscribe: Java
subscribe: C++
subscribe: Python
subscribe: go
11-27 01:41:19.693 30223-30223/com.example.dolphkon.hellokotlin D/HelloRxjavaActivity: onNext: kotlin
onNext: Java
onNext: 下游已关闭,将不再接收任何数据
由以上代码我们可知两点:
- Disposable 并不影响上游继续发射事件
- 当 Disposabl.dispose()触发后,下游将不再继续接收事件
(3) subscribe() 的重载方法
public final Disposable subscribe() {}
public final Disposable subscribe(Consumer<? super T> onNext) {}
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {}
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {}
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Consumer<? super Disposable> onSubscribe) {}
public final void subscribe(Observer<? super T> observer) {}
- 不带任何参数的
subscribe()
表示下游不关心任何事件,你上游尽管发你的数据去吧 - 带有一个
Consumer
参数的方法表示下游只关心onNext事件, 其他的事件我假装没看见, 因此我们如果只需要onNext事件可以这么写
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "emit 1");
emitter.onNext(1);
Log.d(TAG, "emit 2");
emitter.onNext(2);
Log.d(TAG, "emit 3");
emitter.onNext(3);
Log.d(TAG, "emit complete");
emitter.onComplete();
Log.d(TAG, "emit 4");
emitter.onNext(4);
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "onNext: " + integer);
}
});
好了,关于RxJava2 的使用今天我们就暂时介绍到这里,下一篇将介绍 RxJava2 中线程的调度。