天天看點

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

繼續閱讀