我只是搬运工,本来想自己写,但是理解和语言表达真心过不了关,
源码方面,我详细点介绍,
笔记么,好东西我就抄 给 Android 开发者的 RxJava 详解
线程控制Scheduler
1)Scheduler的API
在不指定线程的情况下, RxJava 遵循的是线程不变的原则,即:在哪个线程调用 subscribe()
,就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。如果需要切换线程,就需要用到 Scheduler
(调度器)。
Schedulers.immediate():
直接在当前线程运行,相当于不指定线程。这是默认的Scheduler
。Schedulers.newThread():
总是启用新线程,并在新线程执行操作。Schedulers.io():
I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的Scheduler
。行为模式和newThread()
差不多,区别在于io()
的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下io()
比newThread()
更有效率。不要把计算工作放在io()
中,可以避免创建不必要的线程。Schedulers.computation():
计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个Scheduler
使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在computation()
中,否则 I/O 操作的等待时间会浪费 CPU。- 另外,
Android
还有一个专用的AndroidSchedulers.mainThread()
,它指定的操作将在 Android 主线程运行。
有了这几个 Scheduler ,就可以使用 subscribeOn() 和 observeOn() 两个方法来对线程进行控制了。
subscribeOn()
: 指定 subscribe() 所发生的线程,即 Observable.OnSubscribe 被激活时所处的线程。或者叫做事件产生的线程。observeOn()
: 指定 Subscriber 所运行在的线程。或者叫做事件消费的线程。
Observable.just(1, 2, 3, 4)
.subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer number) {
Log.d(tag, "number:" + number);
}
});
这个其实可以配合compose 使用 下一篇介绍
变换 (也是个人感觉掌握了这个就算入门了)
1)API
- 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);
}
});
这里出现了一个叫做 Func1
的类。它和 Action1
非常相似,也是 RxJava 的一个接口,用于包装含有一个参数的方法。Func1
和 Action
的区别在于, Func1 包装的是有返回值
的方法。另外,和 ActionX
一样,FuncX
也有多个,用于不同参数个数的方法。FuncX
和 ActionX
的区别在 FuncX
包装的是有返回值的方法。
- 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()
有一个相同点:它也是把传入的参数转化之后返回另一个对象。但需要注意,和map()
不同的是, flatMap()
中返回的是个Observable
对象,并且这个Observable
对象并不是被直接发送到了Subscriber
的回调方法中。 flatMap()
的原理是这样的:
使用传入的事件对象创建一个
Observable
对象;并不发送这个
Observable
, 而是将它激活,于是它开始发送事件;- 每一个创建出来的
Observable
发送的事件,都被汇入同一个Observable
,而这个Observable
负责将这些事件统一交给Subscriber
的回调方法。这三个步骤,把事件拆成了两级,通过一组新创建的Observable
将初始的对象『铺平』之后通过统一路径分发了下去。而这个『铺平』就是flatMap()
所谓的 flat。
2) 变换的原理:lift()
这些变换虽然功能各有不同,但实质上都是针对事件序列的处理和再发送
。而在 RxJava 的内部,它们是基于同一个基础的变换方法: lift(Operator)。首先看一下 lift() 的内部实现(仅核心代码):
- 下面是
map()
方法的 内部实现 ,flatmap()
其实就是类似 最后也是用到lift()
// 比如 String 转为 Bitmap ,这样 T 为 String R 为 Bitmap
public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
// 看到没有 ,return lift(new OperatorMap<String , Bitmap>) 注意类型
return lift(new OperatorMap<T, R>(func));
}
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) { // <String,Bitmap>
// 看到没有 返回的是 Observable<String> ,你可能会疑惑 为什么不是 Observable<Bitmap> ,
// 不是要String 转为Bitmap吗 ?
// 如果你是这样想就错了哦,我们这个是 对于map()的内部实现,他并没有转为Observalbe<Bitmap>,而是一个新的Observable<String>
// 这边生成 了新的 被观察者 Observable<String>
return new Observable<R>(new OnSubscribe<R>() {
@Override
public void call(Subscriber<? super R> o) {
try {
// ① hook.onLift其实就是直接返回operator
// 重写这个方法 ,可以被修改,装饰,或者只是取代作为传送的返回,
// 然后调用 call方法 o的类型为 String
/* ②
public interface Func1<T, R> extends Function {
// Bitmap call(Stirng t) 这边就是重点,就是在这边他做了转化,我们就是在这个方法里面 进行自定义的转化
R call(T t);
}
*/
// 这边生成了 第二个 新的 观察者Subscriber<Bitmap>
Subscriber<? super T> st = hook.onLift(operator).call(o);
try {
// 这边调用 Subscriber<Bitmap> 的 onStart()
st.onStart();
// 在 Observable 执行了 lift(Operator) 方法之后,会返回一个新的 Observable,
// 这个新的 Observable 会像一个代理一样,负责接收原始的 Observable 发出的事件,
// 并在处理后发送给 Subscriber --》 这边是个Action1
onSubscribe.call(st);
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
st.onError(e);
}
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
o.onError(e);
}
}
});
}
//*****************************************************************************************
final OnSubscribe<T> onSubscribe;
/**
* 其实 onSubscribe 是Action1 ,这就是为什么 我们的 观察者可以直接使用 new Action1
* Action1<Subscriber<? super T>> 我惊呆了,他的类型是一个 Subscriber,
* 真J8巧妙,我之前还怀疑, 上面那段代码 的onSubscribe.call(st); 难道只能是Action1,那为什么Sbucribe也可以?
* 所以东西还是要清楚,看下来,才知道,才能理解透彻一点
*/
public interface OnSubscribe<T> extends Action1<Subscriber<? super T>> {
// cover for generics insanity
}
/**
* 其实 operator 是 Func1 , 这就是为什么 我们 map中是 new Func1
*/
public interface Operator<R, T> extends Func1<Subscriber<? super R>, Subscriber<? super T>> {
// cover for generics insanity
}
- 这边算是对 RxJava 学习笔记(二)订阅部分的源码补充吧
- 在 被观察者Observable 中, subscribe方法 有多种参数,结合上面的源码这样你应该可以理解为什么可以用onSubscribe.call(str)
public final Subscription subscribe(final Observer<? super T> observer) {
if (observer instanceof Subscriber) {
return subscribe((Subscriber<? super T>)observer);
}
return subscribe(new Subscriber<T>() {
@Override
public void onCompleted() {
observer.onCompleted();
}
@Override
public void onError(Throwable e) {
observer.onError(e);
}
@Override
public void onNext(T t) {
observer.onNext(t);
}
});
}
// 就是这边
public final Subscription subscribe(final Action1<? super T> onNext) {
if (onNext == null) {
throw new IllegalArgumentException("onNext can not be null");
}
return subscribe(new Subscriber<T>() {
@Override
public final void onCompleted() {
// do nothing
}
@Override
public final void onError(Throwable e) {
throw new OnErrorNotImplementedException(e);
}
@Override
public final void onNext(T args) {
onNext.call(args);
}
});
}
public final Subscription subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError) {
if (onNext == null) {
throw new IllegalArgumentException("onNext can not be null");
}
if (onError == null) {
throw new IllegalArgumentException("onError can not be null");
}
return subscribe(new Subscriber<T>() {
@Override
public final void onCompleted() {
// do nothing
}
@Override
public final void onError(Throwable e) {
onError.call(e);
}
@Override
public final void onNext(T args) {
onNext.call(args);
}
});
}
public final Subscription subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError, final Action0 onComplete) {
if (onNext == null) {
throw new IllegalArgumentException("onNext can not be null");
}
if (onError == null) {
throw new IllegalArgumentException("onError can not be null");
}
if (onComplete == null) {
throw new IllegalArgumentException("onComplete can not be null");
}
return subscribe(new Subscriber<T>() {
@Override
public final void onCompleted() {
onComplete.call();
}
@Override
public final void onError(Throwable e) {
onError.call(e);
}
@Override
public final void onNext(T args) {
onNext.call(args);
}
});
}
文章开头那篇文章,我之前看了很多次 在lift()
这一块,但是都没有理解,现在自己做笔记,然后看源码,虽然说不能百分百理解,但是也差不多了