天天看点

RxJava系列之二 变换类操作符详解1

1.回顾

上一篇文章我们主要介绍了RxJava , RxJava 的Observables和 RxJava的just操作符。以及RxJava一些常用的操作。

没看过的抓紧点我去看吧。

其实RxJava有很多的操作符, 而我们学过的just只是创建类操作符的其中一种。以后我会陆续介绍其他的创建类操作符。

文章代码地址:https://github.com/jiang111/RxJavaDemo

2. 变换类操作符之map

开始本篇文章的讲解:

map操作符的具体用法。

map是属于变换操作符。它的作用是对序列的每一项都应用一个函数来变换Observable发射的数据序列(太官方了), 大白话就是你传递一个Observable,然后它返回给你另一个Observable。

看图:

RxJava系列之二 变换类操作符详解1

Map操作符对原始Observable发射的每一项数据应用一个你选择的函数,然后返回一个发射这些结果的Observable

RxJava将这个操作符实现为map函数。这个操作符默认不在任何特定的调度器上执行。

给大家举个例子: 每个模块传递一个url给底层网络请求您框架, 然后底层框架需要将url进行变换, 比如: 添加host。 那么我们就可以通过map来实现。

下面我们就通过map配合Rxandroid 写一个网络请求。在写代码之前请大家在gradle文件中添加 RxAndroid 的jar包 compile ‘io.reactivex:rxandroid:1.0.+’

代码采用了ButterKnife注解, 直接拷贝下来运行可能会报错,请先clone工程,再运行。

public static final String HOST = "http://blog.csdn.net/";

    @Bind(R.id.first_wb)
    WebView mWb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Observable.just("jys1115/article/details/47428843").map(new Func1<String, String>() {
            @Override
            public String call(String s) {
                return HOST + s;
            }
        }).map(new Func1<String, String>() {
            @Override
            public String call(String s) {
                return doNetTask(s);
            }
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        mWb.loadDataWithBaseURL(HOST, s, "text/html", "utf-8", null);
                    }
                });
    }

    private String doNetTask(String s) {

        HttpClient client = new DefaultHttpClient();

        HttpGet get = new HttpGet(s);
        String result;
        try {
            HttpResponse response = client.execute(get);

            if ( == response.getStatusLine().getStatusCode()) {
                result = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
            } else {
                result = "状态行非200";
            }

        } catch (Exception e1) {
            result = e1.getStackTrace().toString();
        }
        return result;

    }
代码就不用注释了,很简单。 代码中用到的Schedulers.newThread()和 AndroidSchedulers.mainThread() 相信大家都懂的, 以后的文章中我也会介绍到。
           

看结果:

RxJava系列之二 变换类操作符详解1

好了, map是个好东西啊, 不要激动, 下面还有更多的好东西等待着我们去探索呢。

3. 变换类操作符之flatMap

突然, boss又出新需求了,刚刚我们写了个网络请求, 然后拿出所有请求的数据, 现在我们不需要那么多数据, 我们只需要city字段和WD字段(运行过上段代码就知道了), 而且这次我不在只给你一个url了,而是给你多个url, 写吧。

boss永远都是这样的。

很多人就开始想了, 那就写个for循环呗,我们最擅长了。哈哈,。 RxJava为我们提供了更方便的操作。flatMap()操作符。

flatMap()操作符的作用是将Observable发射的数据集合变换为Observables集合,然后将这些Observable发射的数据平坦化的放进一个单独的Observable,还是太抽象了。

简单说就是将 一个List 或者数组中的每一条数据都 转换成一个 Observable对象。

那我们就开始写代码吧(代码是最好的老师):

public static final String HOST = "http://www.weather.com.cn";
    List<String> values = new ArrayList<>();
    private String TAG = "SecondActivity2";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        values.add("/adat/sk/101010100.html");
        values.add("/adat/sk/101010100.html");
        values.add("/adat/sk/101010100.html");
        values.add("/adat/sk/101010100.html");
        values.add("/adat/sk/101010100.html");

        Observable.just(values).flatMap(new Func1<List<String>, Observable<?>>() {
            @Override
            public Observable<?> call(List<String> strings) {
                return Observable.from(strings);
            }
        }).cast(String.class).map(new Func1<String, String>() {
            @Override
            public String call(String s) {
                return doNetTaskForString(HOST + s); //取出想要的字段,这里我就不取出来了
            }
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.i(TAG, "value: " + s); 
                    }
                });
    }

    @NonNull
    @Override
    public int getContentView() {
        return R.layout.activity_second2;
    }

    private synchronized String doNetTaskForString(String s) {

        HttpClient client = new DefaultHttpClient();

        Log.i(TAG, "url:" + s);
        HttpGet get = new HttpGet(s);
        String result;
        try {
            HttpResponse response = client.execute(get);
            Log.i(TAG, "state code :" + response.getStatusLine().getStatusCode());
            if ( == response.getStatusLine().getStatusCode()) {
                result = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
            } else {
                result = "状态行非200";
            }

        } catch (Exception e1) {
            result = "抛出了异常" + e1.getMessage();
            e1.printStackTrace();
        }
        return result;

    }
           

结果(这次采取打log的形式):

RxJava系列之二 变换类操作符详解1

这段代码里我们又用到的新的操作符 cast .

cast的作用就是 在发射之前强制将Observable发射的所有数据转换为指定类型。

看图:

RxJava系列之二 变换类操作符详解1

4. 总结

好了,我们总结一下今天学习的内容。我们今天又学习了 两个操作符 flatMap cast, 复习了 just from map 操作符。

下次我们将通过几个栗子把 RxJava剩下的变换类的操作符讲完, 敬请期待吧。

文章代码地址:https://github.com/jiang111/RxJavaDemo

欢迎关注我的微信公众号:androidesigner

通过微信扫描二维码即可关注。

RxJava系列之二 变换类操作符详解1

继续阅读