今天简单介绍下Rxjava里面的map方法
map方法是Rxjava里面使用频率比较高的一个方法,主要用来数据的转化,数据预处理等,比如传一个图片路径,最后得到图片的bitmap,举个栗子:
- 传入一个本地图片路径来得到图片
private String filePath ="/storage/emulated/0/Download/ic_launcher.png";
Observable<Bitmap> sender = Observable.just(filePath).map(new Func1<String, Bitmap>() {
@Override
public Bitmap call(String s) {
return getBitmapFromPath(s);
}
});
Observer<Bitmap> receiver = new Observer<Bitmap>(){
@Override
public void onCompleted() {
//数据接收完成时调用
Log.d("dfy","onCompleted");
}
@Override
public void onError(Throwable e) {
//发生错误时调用
Log.d("dfy","onError");
}
@Override
public void onNext(Bitmap bitmap) {
//数据接收时调用
// Log.d("dfy","onNext");
imgView.setImageBitmap(bitmap);
}
};
sender.subscribe(receiver);
private Bitmap getBitmapFromPath(String path)
{
return BitmapFactory.decodeFile(path);
}
然后运行得到的效果图
点击helloword按钮之后,显示了图片。使用就是这么简单!
OK,接下来分析一波~
我们把上面的代码拆分下
Observable<String> sender1 = Observable.just(filePath);
Observable<Bitmap> sender2 = sender1.map(new Func1<String, Bitmap>() {
@Override
public Bitmap call(String s) {
return getBitmapFromPath(s);
}
});
我们知道,当执行sender2.subscribe(receiver);
时,会回调 这个Observable.OnSubscribe的call()方法,这个Observable对象sender2是map里面new出来的,接下来我们进入map方法里面
public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
return lift(new OperatorMap<T, R>(func));
}
里面又调用了lift方法
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
return new Observable<R>(new OnSubscribe<R>() {
@Override
public void call(Subscriber<? super R> o) {
try {
Subscriber<? super T> st = hook.onLift(operator).call(o);
try {
// new Subscriber created and being subscribed with so 'onStart' it
st.onStart();
onSubscribe.call(st);
} catch (Throwable e) {
// localized capture of errors rather than it skipping all operators
// and ending up in the try/catch of the subscribe method which then
// prevents onErrorResumeNext and other similar approaches to error handling
if (e instanceof OnErrorNotImplementedException) {
throw (OnErrorNotImplementedException) e;
}
st.onError(e);
}
} catch (Throwable e) {
if (e instanceof OnErrorNotImplementedException) {
throw (OnErrorNotImplementedException) e;
}
// if the lift function failed all we can do is pass the error to the final Subscriber
// as we don't have the operator available to us
o.onError(e);
}
}
});
}
看到没,这里new了一个新的Observable对象,然后回调他的OnSubscribe.call方法,看到这行代码Subscriber<? super T> st = hook.onLift(operator).call(o);
简单的意思就是调用operator的call方法,将subscriber作为参数传进去,那这个operator是哪里来的呢,看这里return lift(new OperatorMap<T, R>(func));
map方法里面调用lift的时候new 了一个OperatorMap,这个OperatorMap是实现了operator接口的
public final class OperatorMap<T, R> implements Operator<R, T> {
private final Func1<? super T, ? extends R> transformer;
public OperatorMap(Func1<? super T, ? extends R> transformer) {
this.transformer = transformer;
}
@Override
public Subscriber<? super T> call(final Subscriber<? super R> o) {
return new Subscriber<T>(o) {
@Override
public void onCompleted() {
o.onCompleted();
}
@Override
public void onError(Throwable e) {
o.onError(e);
}
@Override
public void onNext(T t) {
try {
o.onNext(transformer.call(t));
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
onError(OnErrorThrowable.addValueAsLastCause(e, t));
}
}
};
}
}
当调用operator的call方法时,会生成一个Subscriber<? super T> st = hook.onLift(operator).call(o);
对象,注意他的参数,我们map里面func1里面传进去的是String类型,返回值是Bitmap,而Operator的参数顺序正好是反的,也就是说我们调用operator的call方法时,传进去的subscriber是bitmap类型的,返回的值subscriber是String类型的,看到这,你也许就糊涂了,别急,继续往下看,当执行完Subscriber<? super T> st = hook.onLift(operator).call(o);
后又执行了onSubscribe.call(st);
将上面得到的Subscriber st作为参数传进去了,那当前这个onSubscribe又是谁呢?
我们知道sender2是sender1调用map方法创建出来的,所以在map方法里面,这个onSubscribe就是sender1的,也就是说接下来是调用sender1的onSubscribe.call方法,我们追踪生成sender1的just方法,发现
protected ScalarSynchronousObservable(final T t) {
super(new OnSubscribe<T>() {
@Override
public void call(Subscriber<? super T> s) {
/*
* We don't check isUnsubscribed as it is a significant performance impact in the fast-path use cases.
* See PerfBaseline tests and https://github.com/ReactiveX/RxJava/issues/1383 for more information.
* The assumption here is that when asking for a single item we should emit it and not concern ourselves with
* being unsubscribed already. If the Subscriber unsubscribes at 0, they shouldn't have subscribed, or it will
* filter it out (such as take(0)). This prevents us from paying the price on every subscription.
*/
s.onNext(t);
s.onCompleted();
}
});
this.t = t;
}
里面调用了Subscriber的onNext()方法,OK,我们这里传进去的是Subscriber<? super T> st = hook.onLift(operator).call(o);
这个Subscriber对象,参数是string类型,他的onNext方法在operatorMap里面可以看到
@Override
public Subscriber<? super T> call(final Subscriber<? super R> o) {
return new Subscriber<T>(o) {
@Override
public void onCompleted() {
o.onCompleted();
}
@Override
public void onError(Throwable e) {
o.onError(e);
}
@Override
public void onNext(T t) {
try {
o.onNext(transformer.call(t));
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
onError(OnErrorThrowable.addValueAsLastCause(e, t));
}
}
};
}
onNext()方法里面,首先调用transformer.call(t)
这个transformer就是我们传进去的fun1对象,他的call方法就是
将参数just方法里面的String类型参数传进来,得到Bitmap对象,然后调用o.onNext()方法也就是我们这里的
new Func1<String, Bitmap>() {
@Override
public Bitmap call(String s) {
return getBitmapFromPath(s);
}
Observer<Bitmap> receiver = new Observer<Bitmap>(){
@Override
public void onCompleted() {
//数据接收完成时调用
Log.d("dfy","onCompleted");
}
@Override
public void onError(Throwable e) {
//发生错误时调用
Log.d("dfy","onError");
}
@Override
public void onNext(Bitmap bitmap) {
//数据接收时调用
// Log.d("dfy","onNext");
imgView.setImageBitmap(bitmap);
}
};
receiver 对象里面的onNext()方法,将bitmap对象传进来,然后显示在imageview上。
好了,map方法就介绍完了,不知道是否讲解明白了,不过没明白不要紧,多看两遍源码,多想想,应该就能理解了。