本文转自:http://blog.csdn.net/carson_ho/article/details/78179340
前言
Rxjava
由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大 Android
开发者的欢迎。
![Github截图](https://i-blog.csdnimg.cn/blog_migrate/63033ce27fa9d6497b9d120e485803d7.webp?x-image-process=image/format,png)
-
本文主要:
- 面向 刚接触
Rxjava
的初学者 -
提供了一份 清晰、简洁、易懂的Rxjava
入门教程
涵盖 基本介绍、原理 & 具体使用等
-
解决的是初学者不理解Rxjava
原理 & 不懂得如何使用的问题
希望你们会喜欢。
- 本文主要基于
Rxjava 2.0
- 如果读者还没学习过
Rxjava 1.0
也没关系,因为Rxjava 2.0
只是在Rxjava 1.0
上增加了一些新特性,本质原理 & 使用基本相同 - 接下来的时间,我将持续推出
Android
中 Rxjava 2.0
的一系列文章,包括原理、操作符、应用场景、背压等等 ,有兴趣可以继续关注Carson_Ho的安卓开发笔记!!
![示意图](https://i-blog.csdnimg.cn/blog_migrate/0d516437d511cbfbd4610a05047f215b.webp?x-image-process=image/format,png)
目录
![示意图](https://i-blog.csdnimg.cn/blog_migrate/7829b25b9d0eaa866398755b8d1350db.webp?x-image-process=image/format,png)
1. 定义
RxJava:a library for composing asynchronous and event-based programs using observable sequences for the Java VM
- 总结:
RxJava
是一个 基于事件流、实现异步操作的库
2. 作用
实现异步操作
类似于 Android
中的 AsyncTask
、Handler
作用
3. 特点
由于 RxJava
的使用方式是:基于事件流的链式调用,所以使得 RxJava
:
更重要的是,随着程序逻辑的复杂性提高,它依然能够保持简洁 & 优雅
4. 原理
4.1 生活例子引入
- 我用一个生活例子引入 & 讲解
Rxjava
原理: 顾客到饭店吃饭
![示意图](https://i-blog.csdnimg.cn/blog_migrate/5c0254d6c749f0469710a0c2c938f00b.webp?x-image-process=image/format,png)
![流程图](https://i-blog.csdnimg.cn/blog_migrate/27f29eb792040730d5e3f1223acba447.webp?x-image-process=image/format,png)
4.2 Rxjava原理介绍
-
Rxjava
原理 基于 一种扩展的观察者模式
-
Rxjava
的扩展观察者模式中有4个角色:
角色 | 作用 | 类比 |
---|
被观察者(Observable) | 产生事件 | 顾客 |
观察者(Observer) | 接收事件,并给出响应动作 | 厨房 |
订阅(Subscribe) | 连接 被观察者 & 观察者 | 服务员 |
事件(Event) | 被观察者 & 观察者 沟通的载体 | 菜式 |
请结合上述 顾客到饭店吃饭 的生活例子理解:
![示意图](https://i-blog.csdnimg.cn/blog_migrate/b7ddc51b27c3f7b9306cba7914bfd771.webp?x-image-process=image/format,png)
![流程图](https://i-blog.csdnimg.cn/blog_migrate/32c2cf9ff5355d186be1f593d603c21a.webp?x-image-process=image/format,png)
即RxJava
原理可总结为:被观察者 (Observable)
通过 订阅(Subscribe)
按顺序发送事件 给观察者 (Observer)
, 观察者(Observer)
按顺序接收事件 & 作出对应的响应动作。具体如下图:
![示意图](https://i-blog.csdnimg.cn/blog_migrate/8e25bba661134c577bfc3526d6c49ba2.webp?x-image-process=image/format,png)
至此,RxJava
原理讲解完毕。
5. 基本使用
- 本文只关注
RxJava
的基本使用,更深入的RxJava
使用请继续关注Carson_Ho的安卓开发笔记 Rxjava
的使用方式有两种:
- 分步骤实现:该方法主要为了深入说明
Rxjava
的原理 & 使用,主要用于演示说明 - 基于事件流的链式调用:主要用于实际使用
5.1 方式1:分步骤实现
5.1.1 使用步骤
![示意图](https://i-blog.csdnimg.cn/blog_migrate/2688065521dc5f95cb94f646c898bb24.webp?x-image-process=image/format,png)
5.1.2 步骤详解
步骤1:创建被观察者 (Observable
)& 生产事件
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
});
<--扩展:RxJava 提供了其他方法用于 创建被观察者对象Observable -->
Observable observable = Observable.just("A", "B", "C");
String[] words = {"A", "B", "C"};
Observable observable = Observable.from(words);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
步骤2:创建观察者 (Observer
)并 定义响应事件的行为
- 即 开厨房 - 确定对应菜式
- 发生的事件类型包括:
Next
事件、Complete
事件 & Error
事件。具体如下:
![示意图](https://i-blog.csdnimg.cn/blog_migrate/dae3166433dfb0a1b3c3a53cbba6a9f4.webp?x-image-process=image/format,png)
<--方式1:采用Observer 接口 -->
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "对Next事件作出响应" + value);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
};
<--方式2:采用Subscriber 抽象类 -->
Subscriber<String> subscriber = new Subscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "对Next事件作出响应" + value);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
};
<--特别注意:2种方法的区别,即Subscriber 抽象类与Observer 接口的区别 -->
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
步骤3:通过订阅(Subscribe
)连接观察者和被观察者
- 即 顾客找到服务员 - 点菜 - 服务员下单到厨房 - 厨房烹调
- 具体实现
observable.subscribe(observer)
// 或者 observable.subscribe(subscriber);
<-- Observable.subscribe(Subscriber) 的内部实现 -->
public Subscription subscribe(Subscriber subscriber) {
subscriber.onStart();
onSubscribe.call(subscriber);
}
5.2 方式2:优雅的实现方法 - 基于事件流的链式调用
- 上述的实现方式是为了说明
Rxjava
的原理 & 使用 - 在实际应用中,会将上述步骤&代码连在一起,从而更加简洁、更加优雅,即所谓的
RxJava
基于事件流的链式调用
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "对Next事件"+ value +"作出响应" );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
}
}
注:整体方法调用顺序:观察者.onSubscribe()> 被观察者.subscribe()> 观察者.onNext()>观察者.onComplete()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
这种 基于事件流的链式调用,使得RxJava
:
更重要的是,随着程序逻辑的复杂性提高,它依然能够保持简洁 & 优雅。所以,一般建议使用这种基于事件流的链式调用方式实现RxJava
。
特别注意
RxJava 2.x
提供了多个函数式接口 ,用于实现简便式的观察者模式。具体如下:
![示意图](https://i-blog.csdnimg.cn/blog_migrate/08ad9db684500ad10ecf789232fa4803.webp?x-image-process=image/format,png)
以 Consumer
为例:实现简便式的观察者模式
Observable.just("hello").subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println(s);
}
});
6. 实例说明
我将用一个实际工程实例来演示 Rxjava
的使用
6.1 方式1:分步骤实现
步骤1:加入依赖
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
步骤2:直接在MainActivity.java
中实现下述步骤
1. 创建被观察者 (Observable )
& 生产事件
2. 创建观察者 (Observer )
并 定义响应事件的行为
3. 通过订阅(Subscribe)
连接观察者和被观察者
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Rxjava";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
});
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "对Next事件"+ value +"作出响应" );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
};
observable.subscribe(observer);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
![示意图](https://i-blog.csdnimg.cn/blog_migrate/42d1c76e8f3aff50432dbc0bf61a1c04.webp?x-image-process=image/format,png)
6.2 方式2:基于事件流的链式调用方式
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Rxjava";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "对Next事件"+ value +"作出响应" );
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
});
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
7. 额外说明
7.1 观察者 Observer的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) {}
7.2 可采用 Disposable.dispose() 切断观察者 与 被观察者 之间的连接
- 即观察者 无法继续 接收 被观察者的事件,但被观察者还是可以继续发送事件
- 具体使用
Observer<Integer> observer = new Observer<Integer>() {
private Disposable mDisposable;
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接");
mDisposable = d;
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "对Next事件"+ value +"作出响应" );
if (value == 2) {
mDisposable.dispose();
Log.d(TAG, "已经切断了连接:" + mDisposable.isDisposed());
}
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
![示意图](https://i-blog.csdnimg.cn/blog_migrate/ece3d0fb9edda88aecce49e937cbe27f.webp?x-image-process=image/format,png)
8. 总结
- 本文主要对
Rxjava
的入门知识进行讲解,包括基本介绍、原理 & 具体使用等 - 接下来,我将持续推出
Android
中 Rxjava 2.0
的一系列文章,包括原理、操作符、应用场景、背压等等 ,有兴趣可以继续关注Carson_Ho的安卓开发笔记!!
![示意图](https://i-blog.csdnimg.cn/blog_migrate/0d516437d511cbfbd4610a05047f215b.webp?x-image-process=image/format,png)