Rx操作符入门:
创建操作符:
按固定时间间隔发射整数序列的Observable,相当于定时器。
- interval
- range
- repeat
- just ,from
这两个操作符和create是等价得。
Observable observable =Observable.just("杨XX","月xx");
通过调用Subscriber,不断得将事件添加到任务队列中。
变换操作符:
RxJava 提供了对事件序列进行变换的支持,这是它的核心功能之一。所谓变换,就是将事件序列中的对象或整个序列进行加工处理,转换成不同的事件或事件序列。
flatMap操作符将Observable发射的数据集合变换成为Observable集合,然后将发射的数据平坦的放入单独的Observable
1.map
map操作符通过指定一个Func对象,将Obsevable发射的数据按照一定的规则做一些变换操作,然后将变换后的数据发射出去。
- map
- flatMap,cast
- concatMap
- flatMapIterable
- buffer
- groupBy
例子1.将Student类转化成String(学生的名字)
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);
例子2. map()
方法将参数中的 String
对象转换成一个 Bitmap
对象后返回,而在经过 map()
方法后,事件的参数类型也由 String
转为了 Bitmap
。
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);
}
});
例子3:
final String Host="http://blog.csdn.net/";
Observable.just("itachi85")
.map(new Func1<String,String>() {
@Override
public String call(String s) {
return Host+s;
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.d(TAG,"map:"+s);
}
});
结果:
map是一对一的转换,如果需要一对多的转换,需要用到下面的flatMap:
2.flatMap
flatMap操作符将Observable发射的数据集合变换成为Observable集合,然后将发射的数据平坦的放入单独的Observable
一个学生类有多个课程信息,用flatMap来进行转换:
tudent[] 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()
有一个相同点:它也是把传入的参数转化之后返回另一个对象。但需要注意,和 map()
不同的是, flatMap()
中返回的是个 Observable
对象,并且这个 Observable
对象并不是被直接发送到了 Subscriber
的回调方法中。 flatMap()
的原理是这样的:1. 使用传入的事件对象创建一个 Observable
对象;2. 并不发送这个 Observable
, 而是将它激活,于是它开始发送事件;3. 每一个创建出来的 Observable
发送的事件,都被汇入同一个 Observable
,而这个 Observable
负责将这些事件统一交给 Subscriber
的回调方法。这三个步骤,把事件拆成了两级,通过一组新创建的 Observable
将初始的对象『铺平』之后通过统一路径分发了下去。而这个『铺平』就是 flatMap()
所谓的 flat。
过滤操作符
- filter
- elementAt
- distinct
- skip,take
- ignoreElements
- throttleFirst
- throttleFirstWithTimeOut
组合操作符
- startWith
- merge
- concat
- zip
- combineLastest
辅助操作符
- delay
- Do
- subscribeOn observeOn
- timeout
错误处理操作符
- catch
- retry
条件操作符和布尔操作符
Rxjava的线程控制:
在不指定线程的情况下, RxJava 遵循的是线程不变的原则,即:在哪个线程调用 subscribe()
,就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。如果需要切换线程,就需要用到 Scheduler
(调度器)。
1.内置的Scheduler
如果不指定线程,默认是在调用subscribe方法的线程上进行回调的。如果我们想切换线程,就需要使用Scheduler。Rxjava里面内置了下面5个Scheduler。
- Schedulers.immediate():直接在当前线程中运行,它是timeout,timeInterval和timestamp操作符的默认调度器
- Schedulers.newThread():总是启用新线程,并在新线程中执行操作
- Schedulers.io():I/O操作(读写文件,读写数据库,网络信息交互等)所使用的Scheduler。行为模式和newThread差不多,区别在于io()内部实现是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下io()比newThread()更有效率。
- Scheduler.computation():计算所使用的Scheduler,例如图形的计算。这个Scheduler使用固定线程池,大小为cpu核数。不要把I/O操作放在这里,否则IO操作的等待时间会浪费CPU。它是buffer,debouce,interval,sample和skip操作符的默认调度器。
- Scheduler.trampoline():当我们想在当前线程执行一个任务时,并不是立即执行,可以用.trampoline()将他入队。这个调度器将会处理它的队列并且按照按序运行队列中的每一个任务。它是repeat和retry操作符默认的调度器。
另外,RxAndroid也提供了一个常用的Scheduler:
- AndroidScheduler.mainThread()——RxAndroid库中提供的Scheduler,他指定的操作在主线程中进行。
最常用得是Schedulers.io()和AndroidScheduler.mainThread()
2 .控制线程
在RxJava中用subscirbeOn和observeOn操作符来控制线程。
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();
}
});
加载图片就会发生在io线程,设置图片在主线程。
参考资料:《Android进阶之光》 ,http://gank.io/post/560e15be2dca930e00da1083#toc_9