是实现一个异步操作的库,类似于异步任务或handler机制。
RxJava 其实就是提供一套异步编程的 API,这套 API 是基于观察者模式的,而且是链式调用的,所以使用 RxJava 编写的代码的逻辑会非常简洁。
RxJava 有以下三个基本的元素:
首先在 gradle 文件中添加依赖:
implementation 'io.reactivex.rxjava2:rxjava:2.1.4'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onNext("a");
emitter.onNext("b");
emitter.onNext("c");
emitter.onComplete();
Log.e("tag", "产生事件");
}
});
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {
d.dispose();
Log.e("tag", "取消订阅 ");
}
@Override
public void onNext(Object o) {
Log.e("tag", "接收事件:" + o);
}
@Override
public void onError(Throwable e) {
Log.e("tag", " 数据处理出错");
}
@Override
public void onComplete() {
Log.e("tag", "数据处理完成");
}
};
observable.map(new Function() {
@Override
public Object apply(Object o) throws Exception {
return o.toString();
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer);
}
·被观察者发送的事件有以下几种,总结如下表:
总结如下图:
以下就是讲解创建被观察者的各种操作符。
方法预览:
public static
有什么用:
创建一个被观察者
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onNext("a");
emitter.onNext("b");
emitter.onNext("c");
emitter.onComplete();
Log.e("tag", "产生事件");
}
});
上面的代码非常简单,创建 ObservableOnSubscribe 并重写其 subscribe 方法,就可以通过 emitter发射器向观察者发送事件。
然后创建一个观察者,来验证这个被观察者是否成功创建。
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {
// d.dispose();
Log.e("tag", "取消订阅 ");
}
@Override
public void onNext(Object o) {
Log.e("tag", "接收事件:" + o);
}
@Override
public void onError(Throwable e) {
Log.e("tag", " 数据处理出错");
}
@Override
public void onComplete() {
Log.e("tag", "数据处理完成");
}
};
最后用被观察者订阅观察者。
observable.subscribe(observer);
方法预览:
public static
......
public static
有什么用?
创建一个被观察者,并发送事件,发送的事件不可以超过10个以上。
方法预览:
public static
有什么用?
这个方法和 just() 类似,只不过 fromArray 可以传入多于10个的变量,并且可以传入一个数组。
怎么用?
方法预览:
public static
有什么用?
这里的 Callable 是 java.util.concurrent 中的 Callable,Callable 和 Runnable 的用法基本一致,只是它会返回一个结果值,这个结果值就是发给观察者的。
怎么用?
方法预览:
public static
有什么用?
参数中的 Future 是 java.util.concurrent 中的 Future,Future 的作用是增加了 cancel() 等方法操作 Callable,它可以通过 get() 方法来获取 Callable 返回的值。
怎么用?
方法预览:
public static
有什么用?
直接发送一个 List 集合数据给观察者
怎么用?
方法预览:
public static
有什么用?
这个方法的作用就是直到被观察者被订阅后才会创建被观察者。
怎么用?
运行结果:
因为 defer() 只有观察者订阅的时候才会创建新的被观察者,所以每订阅一次就会打印一次,并且都是打印 i 最新的值
方法预览:
public static Observable
......复制代码
有什么用?
当到指定时间后就会发送一个 0L 的值给观察者。
怎么用?
打印结果:
方法预览:
public static Observable
public static Observable
......复制代码
有什么用?
每隔一段时间就会发送一个事件,这个事件是从0开始,不断增1的数字。
怎么用?
从时间就可以看出每隔4秒就会发出一次数字递增1的事件。这里说下 interval() 第三个方法的 initialDelay 参数,这个参数的意思就是 onSubscribe 回调之后,再次回调 onNext 的间隔时间。
方法预览:
public static Observable
public static Observable
有什么用?
可以指定发送事件的开始值和数量,其他与 interval() 的功能一样。
怎么用?
打印结果:
05-21 00:03:01.672 2504-2504/com.example.louder.rxjavademo D/chan: ==============onSubscribe
05-21 00:03:03.674 2504-2537/com.example.louder.rxjavademo D/chan: ==============onNext 2
05-21 00:03:04.674 2504-2537/com.example.louder.rxjavademo D/chan: ==============onNext 3
05-21 00:03:05.674 2504-2537/com.example.louder.rxjavademo D/chan: ==============onNext 4
05-21 00:03:06.673 2504-2537/com.example.louder.rxjavademo D/chan: ==============onNext 5
05-21 00:03:07.674 2504-2537/com.example.louder.rxjavademo D/chan: ==============onNext 6
可以看出被观察者的事件产生,从2开始,总共发送5次,onSubscribe 回调
与onNext回调间隔时间为2秒,事件1秒发送一次。
方法预览:
public static Observable
有什么用?
同时发送一定范围的事件序列。
怎么用?
05-21 00:09:17.202 2921-2921/? D/chan: ==============onSubscribe
==============onNext 2
==============onNext 3
==============onNext 4
==============onNext 5
==============onNext 6
方法预览:
public static Observable
有什么用?
作用与 range() 一样,只是数据类型为 Long
方法预览:
public static
public static
public static
有什么用?
怎么用?
打印结果:
05-26 14:06:11.881 15798-15798/com.example.rxjavademo D/chan: ==================onSubscribe
==================onComplete
换成 never() 的打印结果:
05-26 14:12:17.554 16805-16805/com.example.rxjavademo D/chan: ==================onSubscribe
换成 error() 的打印结果:
05-26 14:12:58.483 17817-17817/com.example.rxjavademo D/chan: ==================onSubscribe
==================onError java.lang.NullPointerException
方法预览:
public final
有什么用?
map 可以将被观察者发送的数据类型转变成其他的类型
怎么用?
以下代码将 Integer 类型的数据转换成 String。
05-21 09:16:03.490 5700-5700/com.example.rxjavademo E/chan: ===================onSubscribe
===================onNext I'm 1
===================onNext I'm 2
===================onNext I'm 3
方法预览:
public final
......
有什么用?
这个方法可以将事件序列中的元素进行整合加工,返回一个新的被观察者。
怎么用?
flatMap() 其实与 map() 类似,但是 flatMap() 返回的是一个 Observerable。现在用一个例子来说明 flatMap() 的用法。
假设一个有一个 Person 类,这个类的定义如下:
public class Person {
private String name;
private List
public Person(String name, List
this.name = name;
this.planList = planList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List
return planList;
}
public void setPlanList(List
this.planList = planList;
}
}
Person 类有一个 name 和 planList 两个变量,分别代表的是人名和计划清单。
Plan 类的定义如下:
public class Plan {
private String time;
private String content;
private List
public Plan(String time, String content) {
this.time = time;
this.content = content;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public List
return actionList;
}
public void setActionList(List
this.actionList = actionList;
}
}
现在有一个需求就是要将 Person 集合中的每个元素中的 Plan 的 action 打印出来。 首先用 map() 来实现这个需求看看:
Observable.fromIterable(personList)
.map(new Function < Person, List < Plan >> () {
@Override
public List < Plan > apply(Person person) throws Exception {
return person.getPlanList();
}
})
.subscribe(new Observer < List < Plan >> () {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(List < Plan > plans) {
for (Plan plan: plans) {
List < String > planActionList = plan.getActionList();
for (String action: planActionList) {
Log.d(TAG, "==================action " + action);
}
}
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
可以看到 onNext() 用了嵌套 for 循环来实现,如果代码逻辑复杂起来的话,可能需要多重循环才可以实现。
现在看下使用 flatMap() 实现:
Observable.fromIterable(personList)
.flatMap(new Function < Person, ObservableSource < Plan >> () {
@Override
public ObservableSource < Plan > apply(Person person) {
return Observable.fromIterable(person.getPlanList());
}
})
.flatMap(new Function < Plan, ObservableSource < String >> () {
@Override
public ObservableSource < String > apply(Plan plan) throws Exception {
return Observable.fromIterable(plan.getActionList());
}
})
.subscribe(new Observer < String > () {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
Log.d(TAG, "==================action: " + s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
从代码可以看出,只需要两个 flatMap() 就可以完成需求,并且代码逻辑非常清晰。
方法预览:
public final
public final
有什么用?
concatMap() 和 flatMap() 基本上是一样的,只不过 concatMap() 转发出来的事件是有序的,而 flatMap() 是无序的。
更多详情请看:
RxJava2 只看这一篇文章就够了 - 掘金