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

继续学习Rx,苦逼苦逼,感觉智商不够用了呢。
主要总结一下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>>()

很眼熟吧,和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);
                    }
                });

抛开OkHttp的部分,这一段代码作的事情,简单来说,就是从网址拿到图片,再把图片加载到activity的imageView中
subscribeOn(Schedulers.io()) 这句话是常用的指定后台获取数据,网络访问通常比较耗时
一旦拿到数据
observeOn(AndroidSchedulers.mainThread()) 切换到主线程,更新UI。
关于subscribeOn和observeOn的具体原理以及区别我还没有弄懂。
以后搞懂了再说吧

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值