RxJava之map方法使用

今天简单介绍下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方法就是
new Func1<String, Bitmap>() {
@Override
public Bitmap call(String s) {
return getBitmapFromPath(s);
}
将参数just方法里面的String类型参数传进来,得到Bitmap对象,然后调用o.onNext()方法也就是我们这里的

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方法就介绍完了,不知道是否讲解明白了,不过没明白不要紧,多看两遍源码,多想想,应该就能理解了。

这里写图片描述

阅读更多
换一批

没有更多推荐了,返回首页