前言:
首次接触RxJava都不太容易接受,因为它的编码方式与我们平时习惯有较大差异。而Rxjava用一个词就可以形容它的功能,那就是异步,它是为了使我们的异步代码书写变得更加简洁更加明了。待你深入了解它之后相信你会喜欢上它。(首次写博客,有什么不对的地方希望大家能指出,谢谢!)
Github上RxJava的项目地址:https://github.com/ReactiveX/RxJava
开始使用RxJava
如果你是使用AS,请在gradle依赖一下拓展库。
compile 'io.reactivex:rxjava:1.0.14'
compile 'io.reactivex:rxandroid:1.0.1'
首次使用Rxjava
RxJava 包含两个重要的类Observable(被观察者)和Subscriber(观察者)。这个两个一般都是成对出现(隐式或者显示)。
用RxJava输出一个 Hello Android.
//创建被观察者
Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello ");
subscriber.onNext("Android!");
subscriber.onCompleted();
}
});
创建一个Observable对象,发送了Hello和Android接着完成。
//创建观察者
Subscriber<String> subscriber = new Subscriber<String>() {
@Override
public void onCompleted() {
Log.d("MainActivity", "onCompleted");
}
@Override
public void onError(Throwable e) {
Log.d("MainActivity", "onError");
}
@Override
public void onNext(String s) {
Log.d("MainActivity", s);
}
};
创建观察者Subscriber,实现抽象方法,onCompleted和onNext对应Observable的next与completede。
订阅事件
observable.subscribe(subscriber);
观察日志会发现输出onCompleted Hello Android!
现在看来是不是变麻烦了?其实是变麻烦了,但是当你用牛刀杀鸡也是这种感觉,所以上面只是RxJava的冰山一角,下面我们来慢慢体会它的强大之处。
简化代码–操作符
操作符分为两种just和from,just所接受的参数是object类型的,而from所接受的参数是集合类型的,看场景使用。
我们先来看看just。
Observable.just("Hello Android!")
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d("MainActivity", s);
}
});
现在看起来是不是简洁了很多?嗯,又出现新的方法了,容我慢慢道来。subscribe可以接受的参数又很多比如Action0、Action1、ActionX….
Action0中的Call方法是无参伍返回值的,可以看成是onCompleted。
Action1中的Call方法是有参伍返回值的,可以看成是onNext。
其他的你可以自己去尝试下。
我们再来看看from的使用。
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王麻子");
Observable.from(list)
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d("MainActivity", s);
}
});
from的使用与just大同小异,只是参数类型不一样。
操作符–map、flatmap
有的时候我们会需要将一种数据格式转化为另一种格式,通常我们的做法是遍历-转换-数据,如果我们数据不止需要转化一次的话,我们就需要多层for循环来转换,这样整理逻辑就很不方便。这个时候我们就可以使用map来代替for。
Observable.just("张三")
.map(new Func1<String, Student >() {
@Override
public Student call(String s) {
return new Student(s);
}
})
.subscribe(new Action1<Student>() {
@Override
public void call(Student student) {
Log.d("MainActivity", "student:" + student);
}
});
这样看起来是不是很神奇?明明只传递了name最后输出的却是student。现在介绍下Func1这个参数的作用,可以看见它有两个泛型,第一个是输入的参数类型,第二个是输出的参数类型,所以就是String和Student。它也有很多兄弟与Action一样,还有Func0、Func1、FuncX…..
下面再介绍下flatmap
相比map这个没那么容易理解了。想想我们会遇到这样的场景,如果我需要输出的不只是学生的名字还有学生的兴趣爱好应该怎么写,通常我们会用双层for来解析,这样我们又回归原始了,如果用flatmap来做就容易多了,请看下面的案列。
Student student = new Student("张三");
list.clear();
list.add("游泳");
list.add("篮球");
list.add("爬山");
student.setHobby(list);
Observable.just(student)
.flatMap(new Func1<Student, Observable<String>>() {
@Override
public Observable<String> call(Student student) {
return Observable.from(student.getHobby());
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
}
});
我们现在看到额Func1的泛型就有很大的不同了,出现了Observable,Call的返回值也变成Observable了。在Call中我们直接返回Observable.from(),并且传入了hobby集合,在subscribe的Action中我们就能拿到每个学生的hobby。
线程切换–schedule
Rxjava最大的特点就是能在各个线程之间来回切换,可以使被观察者和观察者运行在指定的线程中。
Schedulers.immediate(): 运行在当前线程运行,默认的就是在这个。
Schedulers.newThread(): 使用新线程,并在新线程执行操作。
Schedulers.io(): I/O 操作所使用的 Scheduler。
Schedulers.computation(): 计算所使用的 Scheduler。
Observable.create(new Observable.OnSubscribe<String>(){
@Override
public void call(Subscriber<? super String> subscriber) {
Log.d("MainActivity", "当前线程" + Thread.currentThread());
}
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d("MainActivity", "当前线程" + Thread.currentThread());
}
});
subscribeOn指定Observable所运行的线程,observeOn指定subscribe所运行的线程。
如果上面的你都学会了,那么你今后的编程中的异步操作和for都可以使用Rxjava来代替了,今后的代码不再是多层嵌套而是线性编程。当然Rxjava不是万能的,视场景使用才能是代码更简洁。