一简介、Rxjava:一个在java vm上使用可观测的序列来组成异步的、基于事件的程序的库。
简单一点的说就是 实现异步操作的库 用它的主要原因就是简洁,随着逻辑的复杂它依然可以保持简洁
二实现操作的基本对象、Rxjava中主要有四个对象组成Observable被观察者(事件源)、
Observer现在主要运用的是Subscriber抽象类他是对Observer的扩展 (观察者)、
subscribe (订阅)、事件
Observable通过subscrible(订阅)方法与Subscrible进行绑定,绑定之后两个对象就像建立了一条通道一样
Subscrible告诉Observable我需要你的某种状态,你要在变化的时候通知我
三实现步骤、
①、创建观察者Subscrible
观察者决定时间出发的时候有怎样的行为Rxjava中Observer接口的实现方式:
当用just创建Observable就可以简单的实现上面的操作
Observable observable = Observable.just("Hello", "Hi", "Aloha");//仅此一句
用from就更简单了
String[] words = {"Hello", "Hi", "Aloha"};
Observable observable = Observable.from(words);
这样我们的第二步就完成了
③、我们要进行绑定了 也就是订阅了subscribe
observable.subscribe(subscriber);//就一句话就完成了绑定
下面看两个例子:
在不指定线程的情况下, RxJava 遵循的是线程不变的原则,
在哪个线程调用 subscribe(),就在哪个线程生产事件。
在哪个线程生产事件,就在哪个线程消费事件
细心的话可以发现上面的程序有个漏洞 对view的操作应该在UI线程中去操作 所以这里我们需要进行指定
线程操作这样的话我们就用到了Scheduler
这个调度器有几个方法:
Schedulers.immediate(): 直接在当前线程运行
Schedulers.newThread(): 总是启用新线程,并在新线程执行操作
Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler和newThread
差不多io是内部实现的比newThread更有效率所以我们用io
Schedulers.computation(): 计算所使用的 Scheduler
AndroidSchedulers.mainThread():这是android专用的他指定操作在UI线程中进行
这几个方法可以使用subscribeOn(): 指定 subscribe() 所发生的线程和
observeOn(): 指定 Subscriber 所运行在的线程进行设置
所以上面第二个例子可以改成
控制器就是对事件序列就行变换也就是把Observable要进行处理的东西进行加工
然后在传给Subscribe
控制器有下面几个:
.map():对数据进行增加修改
.flatMap():接受一个Observable作为输入同时输出另外一个新生成的Observable
.filter():输入和输出相同的袁术并过滤掉不满足条件的
.take():输出指定数量的结果
下面看一个map的例子
这个例子的意思是输入一个字符串,然后通过map对数据的转换,然后输出一个bitmap图片
这里面出现了一个Func1的类,这个是Rxjava的一个借口,用于包装含有一个参数的方法。
可以看到,map() 方法将参数中的 String 对象转换成一个 Bitmap 对象后返回,
而在经过 map() 方法后,事件的参数类型也由 String 转为了 Bitmap。
这种直接变换对象并返回的,是最常见的也最容易理解的变换。
不过 RxJava 的变换远不止这样,它不仅可以针对事件对象,
还可以针对整个事件队列,这使得 RxJava 变得非常灵活
在看一个flatMap()的例子
这个是一个难点,先看一个例子
假设这么一种需求:假设有一个数据结构『学生』,现在需要打印出一组学生的名字。实现方式很简单:
虽然这样能用map实现只是加一个for循环就可以了
但这样对代码复用就不是很好了 这时候我们就用到了flatMap()
看代码
从代码上看fiatMap和map基本相似单有一点区别
flatMap() 中返回的是个 Observable 对象,并且这个 Observable 对象并不是被直接发送到了 Subscriber 的回调方法中
而是先将Observable对象激活,然后开始发送事件,然后把发送的事件存到统一的一个Observable对象中 等所以所有的事件都存到Observable对象里。
然后由这个统一的Observable一块交给Subscriber的回调方法
Rxjava在android中的应用
Observable进行数据库查询 Subscriber显示结果
Observable为点击事件 Subscriber为响应事件
Observable为点击事件 Subscriber为响应事件
Observable为点击事件 Subscriber为响应事件
简单一点的说就是 实现异步操作的库 用它的主要原因就是简洁,随着逻辑的复杂它依然可以保持简洁
二实现操作的基本对象、Rxjava中主要有四个对象组成Observable被观察者(事件源)、
Observer现在主要运用的是Subscriber抽象类他是对Observer的扩展 (观察者)、
subscribe (订阅)、事件
Observable通过subscrible(订阅)方法与Subscrible进行绑定,绑定之后两个对象就像建立了一条通道一样
Subscrible告诉Observable我需要你的某种状态,你要在变化的时候通知我
三实现步骤、
①、创建观察者Subscrible
观察者决定时间出发的时候有怎样的行为Rxjava中Observer接口的实现方式:
Subscriber<String>subscriber = new Subscriber<String>(){
//事件回调时调用的方法 也是主要执行的方法
@Override
public void onNext(String s){
Log.d(tag,"Item:"+s);
}
//事件队列完结。
//RxJava 不仅把每个事件单独处理,还会把它们看做一个队列。
//RxJava 规定当队列中的时间处理完成的时候调用该方法
@Override
public void onCompleter(){
Log.d(tag,"Completerd!");
}
//事件处理发生错误的时候回调的方法
@Override
public void onError(){
Log.d(tag,"Error");
}
/*它会在 subscribe 刚开始,
而事件还未发送之前被调用
不过这个方法默认为空
因为这个时候没有指定线程
所以某些操作不能执行所以他就不适用了*/
@Override
public void onStart()
{
/*
可以用于做一些准备工作,
例如数据的清零或重置
*/
}
/*
他是onStart的升级版
因为在他执行之前可以指定线程
默认情况下这个方法执行在subscribe(订阅)发生的线程 关于订阅后面会讲到
*/
@Override
public void doOnSubscribe()
{
//可以用于做一些准备工作例如数据的清零或重置
}
}
②、创建被观察者Observable
被观察者决定什么时候出发时间以及出发怎样的事件Rxjava有很多方法创建Observable
create()基本创建方法、just(T...)将传入的参数依次发送出来、from(T[])、将传入的数组后Iterable
拆分成具体对象后依次发送出来
Observable observable = Observable.create(new Observable.OnSubseribe<String>()){
@Override
public void call(Subscriber<? super String>subscriber){
subscriber.onNext("Hello");
subscriber.onNext("Hi");
subscriber.onNext("Aloha");
subscriber.onCompleted();
}
}
/*这里传入了一个 OnSubscribe 对象作为参数。
OnSubscribe 会被存储在返回的 Observable 对象中,
它的作用相当于一个计划表,
当 Observable 被订阅的时候,
OnSubscribe 的 call() 方法会自动被调*/
当被订阅的时候输出为Hello Hi Aloha
当用just创建Observable就可以简单的实现上面的操作
Observable observable = Observable.just("Hello", "Hi", "Aloha");//仅此一句
用from就更简单了
String[] words = {"Hello", "Hi", "Aloha"};
Observable observable = Observable.from(words);
这样我们的第二步就完成了
③、我们要进行绑定了 也就是订阅了subscribe
observable.subscribe(subscriber);//就一句话就完成了绑定
下面看两个例子:
String[] names = ...;
Observable.from(names)
.subscribe(new Action1<String>() {
@Override
public void call(String name) {
Log.d(tag, name);
}
});
//将names中的字符串依次打印出来
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();
}
});
/*由指定的一个 drawable 文件 id drawableRes 取得图片,
并显示在 ImageView 中,并在出现异常的时候打印*/
四、线程控制
在不指定线程的情况下, RxJava 遵循的是线程不变的原则,
在哪个线程调用 subscribe(),就在哪个线程生产事件。
在哪个线程生产事件,就在哪个线程消费事件
细心的话可以发现上面的程序有个漏洞 对view的操作应该在UI线程中去操作 所以这里我们需要进行指定
线程操作这样的话我们就用到了Scheduler
这个调度器有几个方法:
Schedulers.immediate(): 直接在当前线程运行
Schedulers.newThread(): 总是启用新线程,并在新线程执行操作
Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler和newThread
差不多io是内部实现的比newThread更有效率所以我们用io
Schedulers.computation(): 计算所使用的 Scheduler
AndroidSchedulers.mainThread():这是android专用的他指定操作在UI线程中进行
这几个方法可以使用subscribeOn(): 指定 subscribe() 所发生的线程和
observeOn(): 指定 Subscriber 所运行在的线程进行设置
所以上面第二个例子可以改成
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();
}
})
.subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
.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();
}
});
五、控制器
控制器就是对事件序列就行变换也就是把Observable要进行处理的东西进行加工
然后在传给Subscribe
控制器有下面几个:
.map():对数据进行增加修改
.flatMap():接受一个Observable作为输入同时输出另外一个新生成的Observable
.filter():输入和输出相同的袁术并过滤掉不满足条件的
.take():输出指定数量的结果
下面看一个map的例子
Observable.just("images/logo.png") // 输入类型 String
.map(new Func1<String, Bitmap>() {
@Override
public Bitmap call(String filePath) { // 参数类型 String
return getBitmapFromPath(filePath); // 返回类型 Bitmap
}
})
.subscribe(new Action1<Bitmap>() {
@Override
public void call(Bitmap bitmap) { // 参数类型 Bitmap
showBitmap(bitmap);
}
});
});
这个例子的意思是输入一个字符串,然后通过map对数据的转换,然后输出一个bitmap图片
这里面出现了一个Func1的类,这个是Rxjava的一个借口,用于包装含有一个参数的方法。
可以看到,map() 方法将参数中的 String 对象转换成一个 Bitmap 对象后返回,
而在经过 map() 方法后,事件的参数类型也由 String 转为了 Bitmap。
这种直接变换对象并返回的,是最常见的也最容易理解的变换。
不过 RxJava 的变换远不止这样,它不仅可以针对事件对象,
还可以针对整个事件队列,这使得 RxJava 变得非常灵活
在看一个flatMap()的例子
这个是一个难点,先看一个例子
假设这么一种需求:假设有一个数据结构『学生』,现在需要打印出一组学生的名字。实现方式很简单:
Student[] stu = {......};
Subscribe<String> subscribe = new Subscribe<String>(){
@Override
public void onNext(String name) {
Log.d(tag, name);
}
...
}
Observable.from(stu)
.map(Fun()1<String,String>{
@Override
public String call(Student student)
{
return student.getName();
}
})
.subscribe(subscribe);
但是如果我们要输出学生的课程呢 一个学生有很多课程
虽然这样能用map实现只是加一个for循环就可以了
但这样对代码复用就不是很好了 这时候我们就用到了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());
}
})
.filter(这里面添加对student课程的限制,比如不等于空)
.take(这里面填写数字表示想输出的条数)
.subscribe(subscriber);
从代码上看fiatMap和map基本相似单有一点区别
flatMap() 中返回的是个 Observable 对象,并且这个 Observable 对象并不是被直接发送到了 Subscriber 的回调方法中
而是先将Observable对象激活,然后开始发送事件,然后把发送的事件存到统一的一个Observable对象中 等所以所有的事件都存到Observable对象里。
然后由这个统一的Observable一块交给Subscriber的回调方法
Rxjava在android中的应用
Observable进行数据库查询 Subscriber显示结果
Observable为点击事件 Subscriber为响应事件
Observable为点击事件 Subscriber为响应事件
Observable为点击事件 Subscriber为响应事件