1. 程式人生 > >RxAndroid之Action,Func,map,flatmap的簡單用法。

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