RxAndroid之Action,Func,map,flatmap的簡單用法。
阿新 • • 發佈:2018-11-21
主要總結一下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