RxAndroid之Action,Func,map,flatmap的简单用法。


主要总结一下Action,Func,map,flatmap的简单用法,以及线程切换的使用。 
原理,依然不明。
Action
场景:观察者输出一句被观察者传入的句子 
还是萌新的时候,老老实实的用new Subscriber写吧

        Observable.just("我爱你")
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {

                        Log.i(TAG, s);
                    }
                });

用action之后的写法 
二者是等价的 
这里的原理”我觉得”是subscribe()自动将Action1里面的call方法转换成了Subscriber的onNext方法。
  Observable.just("我爱你")
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.i(TAG, s);
                    }
                });
 
map和Func
二者放在一起是因为,我感觉他们两个就是一对儿cp。 
场景:现在有一个家庭,家庭里面有两个人,我需要在传入家庭,而得到家庭成员 
家庭的实体类如下
public class Home {
    List<String> list;

    public Home() {
        list = new ArrayList<>();
        list.add("王元姬");
        list.add("司马昭");
    }

    public List<String> getList() {
        return list;
    }
}
 
常规写法
 final Home home=new Home();
        Observable.create(new Observable.OnSubscribe<List<String>>() {
            @Override
            public void call(Subscriber<? super List<String>> subscriber) {
                subscriber.onNext(home.getList());
            }
        }).subscribe(new Action1<List<String>>() {
            @Override
            public void call(List<String> strings) {
                for (String s :
                        strings) {
                    Log.i(TAG, s);
                }
            }
        });

上面的写法很容易理解,Observable将家庭成员的集合添加到队列,而后subscriber用一个for循环将list里面的人员打印出来。
map和func的组合写法
Home home=new Home();
        Observable.just(home)
                .map(new Func1<Home, List<String>>() {
                    @Override
                    public List<String> call(Home home) {
                        return home.getList();
                    }
                }).subscribe(new Action1<List<String>>() {
                    @Override
                    public void call(List<String> strings) {
                        for (String s:strings) {
                            Log.i(TAG, s);
                        }
                    }
                });
 
二者的作用是一样的,可以看到map和func的组合使用,将参数home,改变成了一个list,整个事件的参数,也变成了list。这里称之为变换。 
其实我们看到for循环很不爽,对吧,也许会想到,把一开始的just(home)改成from(home.getList()),然后用一个map(new Func1(){……}把list变换成String不就好了吗?但是很遗憾,map只能一一变换,也就是说,一个list是不能变换成多个String的。 
于是乎,
flatMap的写法
 Home home=new Home();
        Observable.just(home)
                .flatMap(new Func1<Home, Observable<String>>() {
                    @Override
                    public Observable<String> call(Home home) {
                        return Observable.from(home.getList());
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.i(TAG, s);
                    }
                });
 
看起来可能会很晕,但是仔细一想还是很容易理解的 
要取得家庭成员里面的名字,从传入参数开始,需要经历几个步骤 
传入home=1=》取得家庭成员集合= 2=》取得集合的元素 
其实也就两步需要变换 
map做了什么呢 
map在第1步把home变成了集合,但是因为无法做到第2步,所以只能加入一个for循环在subscriber里面处理 
既然1步做不到,那我就两步好了! 
这个两步就是flatmap
现在来看一下flatpmap的做法
flatMap(new Func1<Home, Observable<String>>()
  ● 1
很眼熟吧,和map一样,其实都是把传入的参数Home,变换成了另外一个类型,当然,这里的类型不再是基本类型,居然是一个新的Observable,而这个Observable是什么样的呢 
return Observable.from(home.getList()); 
这里,恍然大悟,我从原来的Observable里面又创建了一个Observable,由这个Observable来进行后续的事件
总结一下,整个事件经过了以下流程 
Observable(1)传入home= =》faltMap拿到home= =》生成Observable(2)(醒目!!)= =》Observable(2)继续执行subscribe 
而在变换Observable(2)(醒目!!)这一内部,又发生了home= =》String。 
其实聪明如你一定想说,这什么玩意儿,明明可以一句话搞定的:
 Home home=new Home();
        Observable.from(home.getList())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.i(TAG, s);
                    }
                });
 
确实如此,当然复杂的例子我一时半会也想不出来,感觉这样可以解释清楚flatMap的原理。
关于线程切换的简单说明
Observable.create(new Observable.OnSubscribe<Bitmap>() {
            @Override
            public void call(final Subscriber<? super Bitmap> subscriber) {
                OkHttpClient client=new OkHttpClient();
                client.newCall(new Request.Builder().url(PATH3).build())
                        .enqueue(new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {

                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {

                                byte[] data=response.body().bytes();
                                Bitmap bitmap=BitmapFactory.decodeByteArray(data,0,data.length);
                                subscriber.onNext(bitmap);
                                subscriber.onCompleted();
                            }
                        });
            }
        }).subscribeOn(Schedulers.io())//产生subscribe指定在io线程
          .observeOn(AndroidSchedulers.mainThread())//随后的动作在android主线程
                .subscribe(new Action1<Bitmap>() {
                    @Override
                    public void call(Bitmap bitmap) {
                        iMain.show(bitmap);
                    }
                });
  ● 1

猜你喜欢

转载自blog.csdn.net/u013297881/article/details/81286309
今日推荐