RxJava基本使用
首先要知道,Rxjava最出名的东西是什么,为什么火?
通过一个例子来看:下面的代码做的事情就是,在io线程(处理耗时操作读写文件的线程,后面详细介绍)依次发送, 注意是依次,先发1,再发2,再发3(注意just方法后面可以跟不止3个参数,可以到10个。也不止有just方法,还有from等) 然后在io线程将每个数字后面拼接上一个字母a,并返回此字符串,然后切换到主线程,把前面生成的字符串依次打印出来 Observable.just(1, 2, 3) .subscribeOn(Schedulers.io()) //切换线程 .map(new Func1<Integer, String>() { @Override public String call(Integer integer) { return integer+"a"; } }) .observeOn(AndroidSchedulers.mainThread()) //切换线程 .subscribe(new Action1<String>() { @Override public void onNext(String s) { System.out.println(s); } }); 从例子可以看出来,rxjava的强大之处: 1. 线程切换自如:在一条调用链中随意的切换成主线程,io线程等,给耗时获取数据,主线程ui展示提供了很好的解决思路。 2. 链式调用,代码清晰:下面一段代码,一条线下去(如果使用Lambda表达式,显示将更加简单,其实Lambda就是让写的更少了,代码更简便了,省去了以前繁琐的写法,只是一种写法,没有什么神奇之处,入门也很简单) //使用Lambda:上述代码更简单了,更符合阅读习惯了 Observable.just(1, 2, 3) .subscribeOn(Schedulers.io()) //切换到io线程 .map(integer->integer+"a") .observeOn(AndroidSchedulers.mainThread()) //切换到主线程 .subscribe(s-> System.out.println(s);); 3. 结果中间转换,操作符的使用`.map(integer->integer+"a")`可以随意转换成你想要的结果。
1.使用:Normal方式(Rxjava 1.x)
//创建(被观察者--或者叫数据发送者)Observable,将自己需要传递的数据类型通过泛型传入。
//Observable调用订阅者的onNext方法,在达成订阅关系之后,订阅者就回接收到Observable发出的数据,然后进行相应的处理
Observable<User> myObservable = Observable.create(new Observable.OnSubscribe<User>() {
@Override
public void call(Subscriber<? super User> subscriber) {
//此处的subscriber就是我们创建的mySub
subscriber.onNext(new User("张三", "456"));
}
});
//创建(观察者--或者叫接受者)Subscriber
Subscriber<User> mySub = new Subscriber<User>() {
@Override
public void onCompleted() {
//
}
@Override
public void onError(Throwable e) {
//发生异常时的回调
}
@Override
public void onNext(User user) {
}
@Override
public void onStart() {
super.onStart();
}
};
//达成订阅关系
myObservable.subscribe(mySub);
2.偷懒方式
//链式调用的原理就是返回本身
//Action1只关注onNext,不关注onErro和onCompleted,但是也有对应的Action0,和Action1……数字代表参数个数
Observable
.from(userList)
.subscribe(new Action1<User>() {
@Override
public void call(User user) {
}
});
3.线程切换
1. Schedulers.newThread() 启用新线程
2. Schedulers.io() I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。
行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,
因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
3. Schedulers.computation() 固定线程池,图形计算
4. AndroidSchedulers.mainThread() 适配android,运行在主线程(调用此需添加RxAndroid库)
5. Schedulers.immediate() 当前线程
开始的例子
Observable.just(1, 2, 3)
.subscribeOn(Schedulers.io()) //制定观察者创建线程
.observeOn(Schedulers.io()) //制定下面的map转换线程
.map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
return integer+"a";
}
})
.observeOn(AndroidSchedulers.mainThread()) //制定观察者输出为主线程
.subscribe(new Action1<String>() {
@Override
public void onNext(String s) {
System.out.println(s);
}
});
subscribeOn()只能作用于被观察者创建的时候,且只能指定一次,如果指定了多次则以第一次为准。
observeOn()指定在事件传递(加工变换)和最终被处理(观察者)的发生在哪一个调度器。可指定多次,每次指定完都在下一步生效。
4.常用操作符
map操作符
//转换.map-->new Func1<转换前T,转换后S>,就是传入T,返回S,支持返回不同类型 Observable .just(userList) .map(new Func1<List<User>, List<User>>() { @Override public List<User> call(List<User> users) { users.add(new User("丈八", "dfdfa")); return users; } }) .subscribe(new Action1<List<User>>() { @Override public void call(List<User> users) { } });
flatmap
//与map原理相同,只是flatmap返回的一个新的Observable Observable.from(userList) .flatMap(new Func1<User, Observable<String>>() { @Override public Observable<String> call(User user) { return Observable.just(user.getName()); } }) .subscribe(new Action1<String>() { @Override public void call(String aDouble) { } });
6. 其他操作符介绍
1. 创建型
Just():上面介绍过,一次发送
from(): 将一个Iterable, 一个Future, 或者一个数组转换成一个Observable,例子中也有
repeat():创建一个重复发射指定数据或数据序列的Observable。
defer():只有当订阅者订阅才创建Observable;为每个订阅创建一个新的Observable。
range():创建一个发射指定范围的整数序列的Observable。 如range(10,5),则为依次发送10,11,12,13,14,15
interval():Observable.interval(5, TimeUnit.SECONDS)创建一个按照给定的时间间隔发射整数序列的Observable
timer():Observable.timer(5, TimeUnit.SECONDS) 延时5秒发送
empty()--创建一个什么都不做直接通知完成的Observable
error()--创建一个什么都不做直接通知错误的Observable
never()--创建一个不发射任何数据的Observable
2. 过滤型
filter():
take( )
takeLast()
distinct( )过滤掉重复数据
distinctUntilChanged()过滤掉连续重复的数据。
first()只发射第一项数据
last()只发射最后的一项数据。
skip( ) 跳过开始的N项数据
skipLast( ) — 跳过最后的N项数据。
elementAt( ) 发射第N项数据
elementAtOrDefault( )发射第N项数据,如果Observable数据少于N项就发射默认值。
sample( )
throttleLast( )
throttleFirst( )定期发射Observable发射的第一项数据
timeout( )如果在一个指定的时间段后还没发射数据,就发射一个异常
……
……
3. 变换型
map()
FlatMap()
scan()具有累加器的功能,可以将前一个的值传递给后面使用。
buffer( )它定期从Observable收集数据到一个集合,然后把这些数据集合打包发射,而不是一次发射一个。
4. 其他类型
……
……
7. 统一取消订阅
1.x有效
CompositeSubscription来收集Subscription,来统一取消订阅
mCompositeSubscription.add(subscription);
……
……
mCompositeSubscription.unSubscribe();