一概要:
RxJava已经被越来越多的人使用,提及。个人也觉得非常好用,优秀。这里做一个简单的归纳。
1,RxJava是什么:GitHub上介绍(翻译):一个在Java VM上使用可观测的序列来组成异步的,
基于事件的程序的库。简单点:一个实现异步操作的库。类似Handler,与AsyncTask。
2,RxJava优点是什么:相对于Handler/AsyncTask,RxJava使用非常简洁。使用一个链式引用就可以
将整个事件序列串联起来。
3,配置参考github:
https://github.com/ReactiveX/RxJava
https://github.com/ReactiveX/RxAndroid
二原理简析:
#RxJava的异步实现,是通过一个扩展的观察者模式来实现的。
#RxJava有四个基本概念:Observable(被观察者),Observer(观察者),subscribe(订阅),事件。
Observable与Observer通过subscribe来实现订阅关系,从而Observable可以在需要的时候发出事件通知Observer。
#与传统的观察者模式不同,RxJava的回调方法中除了onNext(类似onClick, onEvent),还定义了两个特殊的方法
onError, (事件队列异常),onComplete(事件队列结束语onError互斥)
三使用:
#基本使用
创建Observer(观察者),决定事件触发时的行为。(Subscriber是对Obsever封装了的观察者,比Observer多了
两个方法:onStart(在subscribe刚开始,事件还未被发送之前调用),onunsubscribe(取消订阅)。
Observer<String> observer = new Observer<String>() {
@Override
public void onCompleted() {
LogUtil.i(TAG, "onCompleted");
}
@Override
public void onError(Throwable throwable) {
LogUtil.i(TAG, "onError");
}
@Override
public void onNext(String s) {
LogUtil.i(TAG, "onNext:" + s);
}
};
创建Observable(被观察者),决定事件什么时候触发,以及触发怎么的事件。
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("1 times");
subscriber.onNext("2 times");
subscriber.onNext("3 times");
subscriber.onCompleted();
}
});
#这里OnSubscribe作为create的参数,会被存储在observable对象中,相当于observable的计划表,当Observable
被订阅时,OnSubscribe的call方法就会被调用。然后就会触发订阅者(即观察者的)onNext(三次),onCompleted。
#create是创建事件序列的最基本方法。RxJava还提供其他创建事件序列的快捷方法,from、just...;
from方法:
Observable observable = Observable.from(new String[]{"1 times", "2 times", "3 times"});
//将会依次调用
//onNext("1 times");
//onNext("2 times");
//onNext("3 times");
//onCompleted();
j
ust方法:
Observable observable = Observable.just("1 times", "2 times", "3 times");
//将会依次调用
//onNext("1 times");
//onNext("2 times");
//onNext("3 times");
//onCompleted();
Subscribe订阅,创建Observable与Observer之后,subscribe方法将两者联系起来。
observable.subscribe(observer);
//或
observable.subscribe(subscriber);
subscribe的主要核心代码:
// 注意:这不是 subscribe() 的源码,而是将源码中与性能、兼容性、扩展性有关的代码剔除后的核心代码。
public Subscription subscribe(Subscriber subscriber) {
subscriber.onStart();
onSubscribe.call(subscriber);
return subscriber;
}
#重点onSubscribe.call(subscriber)方法,前面分析的create方法,方法中的参数OnSubscribe,作为ObServable的计划表。
除了subscribe(Observer)和subscribe(Subscriber)方法外,还支持不完整定义回调:
Action1<String> nextAction = new Action1<String>() {
@Override
public void call(String s) {
}
};
Action1<Throwable> errorAction = new Action1<Throwable>() {
@Override
public void call(Throwable o) {
}
};
Action0 completeAction = new Action0() {
@Override
public void call() {
}
};
//自动创建Subscriber,使用nextAction,来定义onNext
observable.subscribe(nextAction);
//自动创建Subscriber,使用nextAction,errorAction来定义onNext与onError
observable.subscribe(nextAction, errorAction);
//自动创建Subscriber,使用nextAction,errorAction,completeAction来定义onNext,onError,onComplete
observable.subscribe(nextAction, errorAction, completeAction);
下面举两个例子:
1,将字符串数组names中的字符串依次打印出来。
//将数组names中的所有字符串打印出来。
String[] names = new String[]{"wangwu", "zhangsan", "lisi"};
Observable.from(names)
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
LogUtil.i(TAG, "name:" + s);
}
});
2,由图片id,取得图片并显示:
int resId = R.drawable.aa2;
Observable.create(new Observable.OnSubscribe<Drawable>() {
@Override
public void call(Subscriber<? super Drawable> subscriber) {
LogUtil.i(TAG, "currentThread:" + Thread.currentThread());
Drawable drawable = MainActivity.this.getResources().getDrawable(R.drawable.aa2);
subscriber.onNext(drawable);
subscriber.onCompleted();
}
})
.subscribe(new Subscriber<Drawable>() {
@Override
public void onStart() {
super.onStart();
LogUtil.i(TAG, "onStart");
}
@Override
public void onNext(Drawable drawable) {
LogUtil.i(TAG, "currentThread:" + Thread.currentThread());
LogUtil.i(TAG, "onNext");
iv_content.setImageDrawable(drawable);
}
@Override
public void onError(Throwable throwable) {
LogUtil.i(TAG, "onError");
}
@Override
public void onCompleted() {
LogUtil.i(TAG, "onCompleted");
}
});
高级使用:
1,变换:map、flatMap:将事件序列中的事件或整个事件序列,加工成不同的事件,或事件序列。
场景一,已知学生数组,打印学生的姓名:
Student[] students = ...;
Subscriber<String> subscriber = new Subscriber<String>() {
@Override
public void onNext(String name) {
Log.d(tag, name);
}
...
};
Observable.from(students)
.map(new Func1<Student, String>() {
@Override
public String call(Student student) {
return student.getName();
}
})
.subscribe(subscriber);
场景二,已知学生数组,打印学生的所选课程(课程不唯一):
我们当然可以使用for循环:
Student[] students = ...;
Subscriber<Student> subscriber = new Subscriber<Student>() {
@Override
public void onNext(Student student) {
List<Course> courses = student.getCourses();
for (int i = 0; i < courses.size(); i++) {
Course course = courses.get(i);
Log.d(tag, course.getName());
}
}
...
};
Observable.from(students)
.subscribe(subscriber);
或者flatMap:
Student[] students = ...;
Subscriber<Course> subscriber = new Subscriber<Course>() {
@Override
public void onNext(Course course) {
Log.d(tag, course.getName());
}
...
};
Observable.from(students)
.flatMap(new Func1<Student, Observable<Course>>() {
@Override
public Observable<Course> call(Student student) {
return Observable.from(student.getCourses());
}
})
.subscribe(subscriber);
#flatMap与map不同,call方法返回的是Observable对象。
线程控制要求,利用subscribeOn与observeOn来实现线程控制。subscribeOn实现的是事件发送所在线程,observeOn
事件消耗所在线程(下一个操作),onserveOn可以调用多次,即事件消耗可以多次线程切换。
Scheduler实现异步操作:
Observable.just(1, 2, 3, 4) // IO 线程,由 subscribeOn() 指定
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.map(mapOperator) // 新线程,由 observeOn() 指定
.observeOn(Schedulers.io())
.map(mapOperator2) // IO 线程,由 observeOn() 指定
.observeOn(AndroidSchedulers.mainThread)
.subscribe(subscriber); // Android 主线程,由 observeOn() 指定
延伸doOnSubscribe,与subscriber的onStart方法一样在subscribe之后,事件发送前被调用。但是不同点是doOnSubscribe可以
被指定线程。默认情况下doOnSubscribe与subscribe所在的线程相同,如果在doOnSubscribe后又subscribeOn()定义线程,则
依从doOnSubscribe之后的最近的subscribeOn所指定线程:
Observable.create(onSubscribe)
.subscribeOn(Schedulers.io())
.doOnSubscribe(new Action0() {
@Override
public void call() {
progressBar.setVisibility(View.VISIBLE); // 需要在主线程执行
}
})
.subscribeOn(AndroidSchedulers.mainThread()) // 指定主线程
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
四避免内存泄漏:
使用CompositeSubscription,收集每一次Subscription,然后在onDestroy中统一注销。
CompositeSubscription compositeSubscription = new CompositeSubscription();//第一步,初始化CompositeSubscrpiton
compositeSubscription.add( //第二步,add Subscription
Observable.from(names)
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
LogUtil.i(TAG, "name:" + s);
}
})
);
@Override
protected void onDestroy() {
super.onDestroy();//在Activity销毁的时候,统一取消订阅,释放资源
if(compositeSubscription.isUnsubscribed()){
compositeSubscription.unsubscribe();
}
}
文章参考:http://gank.io/post/560e15be2dca930e00da1083#toc_1