Rxjava一个在Java VM上使用可观测的序列来组成异步的基于事件的程序的库。异步,简洁,链样结构,是他独有的特点。
在github上的地址:
Rxjava:进入
RxAndroid:进入
想要了解更多关于Rxjava的知识请参见下面博文:
一、基本配置
1、依赖
//rxjava2个
compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.1.6'
接下来我们来看看他使用的模式吧
二、观测者模式
观察者模式形象点就是警察抓小偷的模式。警察(观察者),小偷(被观测者),小偷一动,警察立马做出反应。,我们来了解一下Rxjava的观察者模式
Observable(被观察者),Observer(观察者),通过subscribe( )实现订阅关系,从而 Observable 可以在需要的时候发出事件来通知 Observer。
图解
三、开始使用
1、创建Observer
- 创建方法:new
//observer决定事件触发的时候将有怎样的行为
Observer<String> observer = new Observer<String>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
}
};
/**
* Subscriber是Observer的扩展,使用方式一样
* 实际:在subscribe过程中,Observer先转换为Subscriber再使用
* 细微区别:
* onStart():Subscriber的新增方法-->在 subscribe 刚开始,而事件还未发送之前被调用(做准备工作)
* 他在subscribe 所发生的线程被调用,可以使用 doOnSubscribe() 来指定线程。
* unsubscribe():取消订阅,实现后Subscriber将不再接受事件,调用前可使用 isUnsubscribed()判断
* 因为在 subscribe() 之后, Observable 会持有 Subscriber 的引用,这个引用如果不能
* 及时被释放,将有内存泄露的风险。所以最好保持一个原则:要在不再使用的时候尽快在
* 合适的地方(例如 onPause() onStop() 等方法中)
* 调用 unsubscribe() 来解除引用关系,以避免内存泄露的发生。
*
*/
Subscriber<String> subscriber = new Subscriber<String>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
}
};
2、创建Observable
- create
//Observable它决定什么时候触发事件以及触发怎样的事件
/**
*
* 可以看到,这里传入了一个 OnSubscribe 对象作为参数。
* OnSubscribe 会被存储在返回的 Observable 对象中,它的作用相当于一个计划表,
* 当 Observable 被订阅的时候,OnSubscribe 的 call() 方法会自动被调用,
* 事件序列就会依照设定依次触发(对于上面的代码,就是观察者Subscriber
* 将会被调用三次 onNext() 和一次 onCompleted())。这样,由被观察者调用
* 了观察者的回调方法,就实现了由被观察者向观察者的事件传递,即观察者模式。
*/
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("hello");
subscriber.onNext("hi");
subscriber.onNext("hahah");
subscriber.onCompleted();
}
});
- just
just函数,它接受一至九个参数,返回一个按参数列表顺序发射这些数据的Observable。
Observable observable = Observable.just("Hello", "Hi", "Aloha");
// 将会依次调用:
// onNext("Hello");
// onNext("Hi");
// onNext("Aloha");
// onCompleted();
- from
/**
* 传数组,返回一个按参数列表顺序发射这些数据的Observable
* 将会依次调用:
* onNext("Hello");
* onNext("Hi");
* onNext("Aloha");
* onCompleted();
*/
String[] words = {"Hello", "Hi", "Aloha"};
Observable observable = Observable.from(words);
3、实现订阅subscribe()
- 分写
//用上面的方法 创建对象然后用subscribe()建立联系
observable.subscribe(observer);
- 合写(推荐)
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello");
subscriber.onNext("RxJava");
subscriber.onCompleted();
}
}).subscribe(new Observer<String>() {
@Override
public void onCompleted() {
Logger.d("onCompleted()");
}
@Override
public void onError(Throwable e) {
Logger.d("onError(Throwable e)");
}
@Override
public void onNext(String s) {
Logger.d(s);
}
});
方法
map()使用
需求:得到多个Student对象里的name属性并保存在list中
代码实现:
//封装一个学生课时的集合
List<Course> mCourseList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Course course = new Course("课程"+i);
mCourseList.add(course);
}
Students stu = new Students("张三",mCourseList);
Students stu1 = new Students("王五",mCourseList);
Students[] arrStu = {stu,stu1};
//map--一对一的转换(这里只能打印一个多个呢)
Observable.from(arrStu)
.map(new Func1<Students, String>() {
@Override
public String call(Students students) {
return students.getName();
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
mTvMap.setText(s);
}
});
//map可以连续使用
//多个用flatmap()
Observable.from(arrStu)
.flatMap(new Func1<Students, Observable<Course>>() {
@Override
public Observable<Course> call(Students students) {
return Observable.from(students.getCourseList());
}
}).subscribe(new Action1<Course>() {
@Override
public void call(Course course) {
LogUtil.e("课程-->"+course.getCourseName());
}
});
Action使用
- Action0
//只有一个方法call(),无参无返回值,--因为onCompleted()也是因此Action0可以当做一个包装对象将 onCompleted() 的内容打包起来将自己作为一个参数传入 subscribe() 以实现不完整定义的回调,这样其实也可以看做将 onCompleted() 方法作为参数传进了 subscribe(),相当于其他某些语言中的『闭包』
Action0 onCompletedAction = new Action0() {
// onCompleted()
@Override
public void call() {
Log.d(tag, "completed");
}
};
- Action1 (使用条件:不关心OnComplete和OnError只需在onNext的时候做一些处理)
//只有一个call方法无返回值,有一参数,由于 onNext(T obj) 和 onError(Throwable error) 也是单参数无返回值的,因此 Action1 可以将 onNext(obj) 和 onError(error) 打包起来传入 subscribe() 以实现不完整定义的回调。
Action1<String> onNextAction = new Action1<String>() {
// onNext()
@Override
public void call(String s) {
Log.d(tag, s);
}
};
Action1<Throwable> onErrorAction = new Action1<Throwable>() {
// onError()
@Override
public void call(Throwable throwable) {
// Error handling
}
};
- 运用这两个Action(实现不完整回调)
// 自动创建 Subscriber ,并使用 onNextAction 来定义 onNext()
observable.subscribe(onNextAction);
// 自动创建 Subscriber ,并使用 onNextAction 和 onErrorAction 来定义 onNext() 和 onError()
observable.subscribe(onNextAction, onErrorAction);
// 自动创建 Subscriber ,并使用 onNextAction、 onErrorAction 和 onCompletedAction 来定义 onNext()、 onError() 和 onCompleted()
observable.subscribe(onNextAction, onErrorAction, onCompletedAction);
注意: 不止0,1两个Action还有其他的
源码分析
Observable.subscribe(Subscriber) 的内部实现(仅核心代码):
// 注意:这不是 subscribe()的源码,而是将源码中与性能、兼容性、扩展性有关的代码剔除后的核心代码。
//call()事件发送的逻辑开始运行,Observable并不是在创建的时候立即开始发送事件,而是在他被订阅的时候即当subscribe()方法执行的时候
// 如果需要看源码,可以去 RxJava 的 GitHub 仓库下载。
// 将传入的 Subscriber 作为 Subscription 返回。这是为了方便 unsubscribe().
public Subscription subscribe(Subscriber subscriber) {
subscriber.onStart();
onSubscribe.call(subscriber);
return subscriber;
}
案列分析
打印字符串数组names
String[] names = {"张珊", "李四", "王五"};
Observable.from(names)
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Logger.d(s);
}
});
由 id 取得图片并显示
int drawableRes = ...;
ImageView imageView = ...;
Observable.create(new OnSubscribe<Drawable>() {
@Override
public void call(Subscriber<? super Drawable> subscriber) {
Drawable drawable = getTheme().getDrawable(drawableRes));
subscriber.onNext(drawable);
subscriber.onCompleted();
}
}).subscribe(new Observer<Drawable>() {
@Override
public void onNext(Drawable drawable) {
imageView.setImageDrawable(drawable);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Toast.makeText(activity, "Error!", Toast.LENGTH_SHORT).show();
}
});
Schedulers调度器
定义
不指定线程默认同一线程执行消费生产订阅,切换线程用的调度器。