RxJava是什么
RxJava是一种异步方式:类似于android中的AsyncTask 和Handler ,RxJava并不是一个”拿来就能用”的项目,他需要我们像学习门新语言一样从语法–>词汇–>用法的学习过程
作用是什么
用于:逻辑的简洁,并不是单纯的代码量少
RxJava 的使用
- 创建一个被观察者
Observable<String> myObservable = Observable.create(
new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> sub) {
sub.onNext("Hello, world!");
sub.onCompleted(); //标记完成
}
}
);
2.创建一个Subscriber来处理Observable对象发出的字符串
Subscriber<String> mySubscriber = new Subscriber<String>() {
@Override
public void onNext(String s) { System.out.println(s); }
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) { }
};
3.通过subscribe函数就可以将我们定义的myObservable对象和mySubscriber对象关联起来,这样就完成了subscriber对observable的订阅。
myObservable.subscribe(mySubscriber);//订阅
以上代码简化
RxJava 提供了很多简化创建Observable对象的方法
如:Observable.just(),用来创建只发出一个事件就结束的Observable对象
//创建Observable 简化代码
Observable<String> myObservable = Observable.just("Hello, world!");
//简化Subscriber,在Subscriber中我们关注的只有onNext 一个方法,这时候就可以使用Action1 类
Action1<String> onNextAction = new Action1<String>(){
@Override
public void call(String s) {
Log.e("onCompleted", s);
}
};
//订阅 subscribe方法有一个重载版本,接受三个Action1类型的参数,分别对应OnNext,OnComplete, OnError函数。
//这里我们并不关心onError和onComplete,所以只需要第一个参数就可以
myObservable.subscribe(onNextAction);
再简化
Observable.just("Hello, world!")
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.e("call", s);
}
});
错误处理
onComplete()和onError()函数。这两个函数用来通知订阅者,被观察的对象将停止发送数据以及为什么停止(成功的完成或者出错了)
RxJava 中的操作符
1. 操作符(map)
作用:操作符用于在Observable和最终的Subscriber之间修改Observable发出的事件,就是用来把把一个事件转换为另一个事件的
案例:在hello world中加上我的签名,会想到要去修改被观察者,如果加上签名这个需求只针对于某个订阅者,那么去修改被观察者显然不行,这个时候就用到了map操作符,变换Observable对象
Observable.just("Hello, world!")
.map(new Func1<String, String>() {
@Override
public String call(String s) {
return s + " RxJava";
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.e("call", s);
}
});
改变数据类型的observable对象
Observable.just("Hello, world!")
.map(new Func1<String, Integer>() {
@Override
public Integer call(String s) {
return s.hashCode();
}
})
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.e("call", integer.toString());
}
});
这里出现了一个叫做 Func1 的类。它和 Action1 非常相似,也是 RxJava 的一个接口,用于包装含有一个参数的方法。 另外,和 ActionX 一样, FuncX 也有多个,用于不同参数个数的方法。FuncX 和 ActionX 的区别在 FuncX 包装的是有返回值的方法。
Observable和Subscriber可以做任何事情
Observable可以是一个数据库查询,Subscriber用来显示查询结果;Observable可以是屏幕上的点击事件,Subscriber用来响应点击事件;Observable可以是一个网络请求,Subscriber用来显示请求结果。Observable和Subscriber是独立于中间的变换过程的。
在Observable和Subscriber中间可以增减任何数量的map。整个系统是高度可组合的,操作数据是一个很简单的过程。
2.操作符from
操作数组或者集合中每个数据,不需要使用for 来遍历
Observable.from()方法,它接收一个集合作为输入,然后每次输出一个元素给subscriber:
案例:根据输入的字符串返回一个网站的url列表(搜索引擎)
query("Hello, world!")
.subscribe(new Action1<List<String>>() {
@Override
public void call(List<String> strings) {
for(String s:strings){
Log.e("call", s);
}
}
});
使用from操作符
query("Hello, world!")
.subscribe(new Action1<List<String>>() {
@Override
public void call(List<String> strings) {
// for(String s:strings){
// Log.e("call", s);
// }
Observable.from(strings)
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.e("call", s);
}
});
}
});
多个嵌套的subscription,进行修改
3.操作符(flatMap())
Observable.flatMap()接收一个Observable的输出作为输入,同时输出另外一个Observable
query("Hello, world!")
.flatMap(new Func1<List<String>, Observable<String>>() {
@Override
public Observable<String> call(List<String> strings) {
return Observable.from(strings);
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.e("call", s);
}
});
flatMap()可以返回任何它想返回的Observable对象。
4.操作符merge,合并观察者对象
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = new ArrayList<String>();
list1.add("1");
list1.add("2");
list1.add("3");
list2.add("a");
list2.add("b");
list2.add("c");
Observable mObservable1 = Observable.from(list1);
Observable mObservable2 = Observable.from(list2);
//合并数据 先发送observable2的全部数据,然后发送 observable1的全部数据
Observable mObservable3 = Observable.merge(mObservable2, mObservable1);
mObservable3.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("call3",o.toString());
}
});
5. 操作符zip
zip 操作符,合并多个观察对象的数据。并且允许 Func2()函数重新发送合并后的数据
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = new ArrayList<String>();
list1.add("1");
list1.add("2");
list1.add("3");
list2.add("a");
list2.add("b");
list2.add("c");
Observable mObservable1 = Observable.from(list1);
Observable mObservable2 = Observable.from(list2);
//合并Observable数据 ,并重新发送组合后的数据
Observable mObservable3 = Observable.zip(mObservable1, mObservable2, new Func2<String,String,String>() {
@Override
public String call(String s, String s2) {
return s+s2;
}
});
mObservable3.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("zip === ",o.toString());
}
});
6. scan累加器操作符的使用
Observable mObservable = Observable.just(1, 2, 3, 4, 5);
//返回相加结果
Observable mObservableScan = mObservable.scan(new Func2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer o, Integer o2) {
return o + o2;
}
});
mObservableScan.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("scan == ", o.toString());
}
});
打印结果
D/scan ==: 1
D/scan ==: 3
D/scan ==: 6
D/scan ==: 10
D/scan ==: 15
7. filter 过滤操作符的使用
满足结果才会发送
Observable mObservable = Observable.just(1, 2, 3, 4, 5, 6, 7);
//过滤
Observable mObservableFilter = mObservable.filter(new Func1<Integer,Boolean>() {
@Override
public Boolean call(Integer o) {
//数据大于4的时候才会被发送
return o > 4;
}
});
mObservableFilter.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("filter == ", o.toString());
}
});
结果
D/filter ==: 5
D/filter ==: 6
D/filter ==: 7
8. 消息数量过滤操作符的使用
take :取前n个数据
takeLast:取后n个数据
first 只发送第一个数据
last 只发送最后一个数据
skip() 跳过前n个数据发送后面的数据
skipLast() 跳过最后n个数据,发送前面的数据
Observable mObservable = Observable.just(1, 2, 3, 4, 5, 6, 7);
//take 发送前三个数据
Observable mObservableTake = mObservable.take(3);
mObservableTake.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("take == ", o.toString());
}
});
//takeLast 发送后三个数据
Observable mObservableTakeLast = mObservable.takeLast(3);
mObservableTakeLast.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("takeLast",o.toString());
}
});
//first 只发送第一个数据
Observable mObservableFirst = mObservable.first();
mObservableFirst.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("first === ",o.toString());
}
});
//last 只发送最后一个数据
Observable mObservableLast = mObservable.last();
mObservableLast.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("last === ",o.toString());
}
});
//skip 跳过前2个数据发送后面的数据
Observable mObservableSkip = mObservable.skip(2);
mObservableSkip.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("skip === ",o.toString());
}
});
//skipLast 跳过最后2个数据发送后面的数据
Observable mObservableSkipLast = mObservable.skipLast(2);
mObservableSkipLast.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("skipLast === ",o.toString());
}
});
结果
D/take ==: 1
D/take ==: 2
D/take ==: 3
D/takeLast: 5
D/takeLast: 6
D/takeLast: 7
D/first ===: 1
D/last ===: 7
D/skip ===: 3
D/skip ===: 4
D/skip ===: 5
D/skip ===: 6
D/skip ===: 7
D/skipLast ===: 1
D/skipLast ===: 2
D/skipLast ===: 3
D/skipLast ===: 4
D/skipLast ===: 5
9. elementAt 、elementAtOrDefault
注意:elementAt() 发送数据序列中第n个数据 ,序列号从0开始,如果该序号大于数据序列中的最大序列号,则会抛出异常,程序崩溃,所以在用elementAt操作符的时候,要注意判断发送的数据序列号是否越界
Observable mObservable = Observable.just(1, 2, 3, 4, 5, 6, 7);
Observable mObservableElementAt = mObservable.elementAt(2);
mObservableElementAt.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("elementAt === ", o.toString());
}
});
// elementAtOrDefault( int n , Object default ) 发送数据序列中第n个数据 ,序列号从0开始。
// 如果序列中没有该序列号,则发送默认值
Observable mObservableElementAtOrDefault = mObservable.elementAtOrDefault(8,0);
mObservableElementAtOrDefault.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("elementAtOrDefault === ",o.toString());
}
});
结果
D/elementAt ===: 3
D/elementAtOrDefault ===: 0
10.startWith() 插入数据
在已有数据之前插入数据,数据类型可以是普通类型和Observable 对象
Observable mObservable = Observable.just("aa","bb","cc");
Observable mObservableStartWith = mObservable.startWith("11", "22");
mObservableStartWith.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("StartWith 插入普通数据", o.toString());
}
});
//插入Observable对象
ArrayList<String> list = new ArrayList<String>();
list.add("ww");
list.add("tt");
mObservable.startWith(Observable.from(list))
.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("startWith 插入Observable 对象",o.toString());
}
});
结果
D/StartWith 插入普通数据: 11
D/StartWith 插入普通数据: 22
D/StartWith 插入普通数据: aa
D/StartWith 插入普通数据: bb
D/StartWith 插入普通数据: cc
D/startWith 插入Observable 对象: ww
D/startWith 插入Observable 对象: tt
D/startWith 插入Observable 对象: aa
D/startWith 插入Observable 对象: bb
D/startWith 插入Observable 对象: cc
11.delay操作符,延迟数据发送
只限制第一条数据发送的时间
Observable mObservable = Observable.just("aa","bb","cc");
//延迟数据发射的时间,仅仅延时一次,也就是发射第一个数据前延时。发射后面的数据不延时
Observable mObservableDelay = mObservable.delay(2, TimeUnit.SECONDS);//延迟两秒发送
mObservableDelay.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("delay ==", o.toString());
}
});
12. interval 轮询操作符,循环发送数据,数据从0开始递增
private Subscription mSubscription;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//参数一:延迟时间 参数二:间隔时间 参数三:时间颗粒度 MILLISECONDS 每秒一次
Observable mObservable = Observable.interval(3000, 1000, TimeUnit.MILLISECONDS);
mSubscription= mObservable.subscribe(new Action1() {
@Override
public void call(Object o) {
Log.d("interval == ", o.toString());
}
});
}
//销毁的时候停止轮询
@Override
protected void onDestroy() {
super.onDestroy();
if(mSubscription !=null){
mSubscription.unsubscribe();
}
}
结果
D/interval ==: 0
D/interval ==: 1
D/interval ==: 2
D/interval ==: 3
D/interval ==: 4
D/interval ==: 5
D/interval ==: 6
D/interval ==: 7
D/interval ==: 8
I/[Gralloc]: gralloc_unregister_buffer line 259 size3686400 base0x603ef000 phys_addr0 share_fd55 usage0x900 ion_hnd_debug0x2
I/[Gralloc]: gralloc_unregister_buffer line 259 size3686400 base0x614d4000 phys_addr0 share_fd60 usage0x900 ion_hnd_debug0x7
D/interval ==: 9
13.doOnNext() 操作符,在每次 OnNext() 方法被调用前执行
Observable mObservable = Observable.just("1", "2", "3", "4");
mObservable.doOnNext(new Action1() {
@Override
public void call(Object o) {
Log.d("doOnNext call",o.toString());
}
}).subscribe(new Observer() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Object o) {
Log.d("onNext",o.toString());
}
});
结果
D/doOnNext call: 1
D/onNext: 1
D/doOnNext call: 2
D/onNext: 2
D/doOnNext call: 3
D/onNext: 3
D/doOnNext call: 4
D/onNext: 4
14. throttleFirst 操作符
在一段时间内,只取第一个事件,然后其他事件都丢弃。
使用场景:1、button按钮防抖操作,防连续点击 2、百度关键词联想,在一段时间内只联想一次,防止频繁请求服务器
Subscription mSubscription;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//使用interval 达到每秒发送一个,在3秒内只取一个事件,其他的丢失
mSubscription = Observable.interval(1, TimeUnit.SECONDS)
.throttleFirst(3, TimeUnit.SECONDS)
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
Log.d("throttleFirst == ", aLong.toString());
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mSubscription != null) {
mSubscription.unsubscribe();
}
}
结果
D/throttleFirst ==: 0
D/throttleFirst ==: 4
D/throttleFirst ==: 7
D/throttleFirst ==: 10
D/throttleFirst ==: 13
D/throttleFirst ==: 16
D/throttleFirst ==: 19
D/throttleFirst ==: 22
D/throttleFirst ==: 25
15.distinct 过滤重复的数据
ArrayList<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("1");
list.add("3");
list.add("4");
list.add("2");
list.add("2");
list.add("1");
Observable.from(list)
.distinct()
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d("distinct == ", s);
}
});
结果
D/distinct ==: 1
D/distinct ==: 2
D/distinct ==: 3
D/distinct ==: 4
16. distinctUntilChanged() 过滤连续重复的数据
ArrayList<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("1");
list.add("3");
list.add("4");
list.add("2");
list.add("2");
list.add("1");
Observable.from(list)
.distinct()
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d("distinct == ", s);
}
});
Observable.from(list)
.distinctUntilChanged()//过滤连续重复的数据
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d("distinctUntilChange == ", s);
}
});
结果
D/distinctUntilChanged ==: 1
D/distinctUntilChanged ==: 2
D/distinctUntilChanged ==: 1
D/distinctUntilChanged ==: 3
D/distinctUntilChanged ==: 4
D/distinctUntilChanged ==: 2
D/distinctUntilChanged ==: 1