1遇到問題:
我們在過長的時間里,習(xí)慣了以往事情一步步的處理,這里我講的一步步的處理,指的是一系列的事件分步進行,比如有如下需求,進入activity之后需要立馬進行如下操作:
先獲取用戶列表》》界面顯示用戶列表
獲取每個用戶的詳細信息》》將列表item設(shè)置為可點擊
獲取每個用戶的頭像》》列表中的用戶頭像顯示出來
對于用戶的頭像進行壓縮》》輸出壓縮成功日志到控制臺
將壓縮后的頭像存儲》》輸出保存成功日志到控制臺
很明顯,這一系列的事件如果按照以往的子線程調(diào)度,然后handler切換更新ui,必定會使代碼變得冗長而那一閱讀,代碼的縮進也將像進入了地獄般,有人會說,以上步驟可以通過服務(wù)器返回足夠恰當?shù)臄?shù)據(jù)一步完成。其實這里僅僅做一個例子,況且有些情況,服務(wù)端人員并不能溝通到的,比如你需要調(diào)用第三方服務(wù)的接口,他們不會為了讓你方便一些就去對他們整個架構(gòu)大動干戈的;
2,問題思考:
既然傳統(tǒng)的方式看起來很麻煩,那么有沒有解決方法?如果目前我們不知道有Rxjava這個東西,讓我們自己去封裝一個處理類似需求的解決方案該怎么辦?我會思考將所有的處理都放到一個線程中去,然后在每一步結(jié)束的時候通過handler更新ui,類似如下偽代碼:
new Thread(new Runnable() {
? ? @Override
? ? public void run() {
? ? ? ? //獲取用戶列表
? ? ? ? List users = getUserList();
? ? ? ? mHander.post(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? //更新ui
? ? ? ? ? ? ? ? showUserList();
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? //獲取每個用戶詳情
? ? ? ? List userDetails = new ArrayList<>();
? ? ? ? for (int i = 0; i < users.size(); i++) {
? ? ? ? ? ? UserDetail userDetail = getUserDetail(users.get(i).getId());
? ? ? ? ? ? userDetails.add(userDetail);
? ? ? ? ? ? final int finalI = i;
? ? ? ? ? ? mHander.post(new Runnable() {
? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? ? ? //更新ui
? ? ? ? ? ? ? ? ? ? updateListViewClickable(finalI);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? }
? ? ? ? //獲取每個用戶的頭像
? ? ? ? List bitmaps = new ArrayList<>();
? ? ? ? for (int i = 0; i < userDetails.size(); i++) {
? ? ? ? ? ? UserDetail userDetail = userDetails.get(i);
? ? ? ? ? ? final Bitmap bitmap = getUserThumb(userDetail);
? ? ? ? ? ? final int finalI = i;
? ? ? ? ? ? mHander.post(new Runnable() {
? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? ? ? //更新ui
? ? ? ? ? ? ? ? ? ? updateUserHeader(finalI, bitmap);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? }
? ? ? ? //壓縮圖片
? ? ? ? for (int i = 0; i < bitmaps.size(); i++) {
? ? ? ? ? ? Bitmap bitmap = bitmaps.get(i);
? ? ? ? ? ? final Bitmap cbitmap = compressBitmap(bitmap);
? ? ? ? }
? ? ? ? mHander.post(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? //更新ui
? ? ? ? ? ? ? ? ToastUtils.showShort("壓縮圖片成功");
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? //保存圖片
? ? ? ? for (int i = 0; i < bitmaps.size(); i++) {
? ? ? ? ? ? Bitmap bitmap = bitmaps.get(i);
? ? ? ? ? ? saveBitmap(bitmap);
? ? ? ? }
? ? ? ? mHander.post(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? //更新ui
? ? ? ? ? ? ? ? ToastUtils.showShort("保存圖片成功");
? ? ? ? ? ? }
? ? ? ? });
? ? }
});
這樣做似乎還算簡潔(其中有許多不合理的地方,比如圖片的一些列處理可以一個循環(huán)搞定,這里僅僅做一特例,不必深究),也解決了地獄似得回調(diào),但似乎需要優(yōu)化的地方超級多:
?1,線程的創(chuàng)建與管理,代碼執(zhí)行線程的指定
?2,線程的切換
?3,代碼編寫麻煩
?4,數(shù)據(jù)流處理很不完善
3,基于以上問題的解決:
于是官方出品了自帶線程管理,線程切換,鏈式變成,完善數(shù)據(jù)操作符的Rxjava,如果帶著以上問題再去審視Rxjava會好理解的多吧,那么我們?nèi)绻凑誖xjava的方式實現(xiàn)以上代碼是什么樣子的呢?偽代碼如下:
Observable.create(new ObservableOnSubscribe() {
? ? @Override
? ? public void subscribe(ObservableEmitter emitter) throws Exception {
? ? ? ? //獲取用戶列表
? ? ? ? List users = getUserList();
? ? ? ? emitter.onNext(users);
? ? ? ? //獲取每個用戶詳情
? ? ? ? List userDetails = new ArrayList<>();
? ? ? ? for (int i = 0; i < users.size(); i++) {
? ? ? ? ? ? UserDetail userDetail = getUserDetail(users.get(i).getId());
? ? ? ? ? ? userDetails.add(userDetail);
? ? ? ? ? ? emitter.onNext(i);
? ? ? ? }
? ? ? ? //獲取每個用戶的頭像
? ? ? ? List bitmaps = new ArrayList<>();
? ? ? ? for (int i = 0; i < userDetails.size(); i++) {
? ? ? ? ? ? UserDetail userDetail = userDetails.get(i);
? ? ? ? ? ? final Bitmap bitmap = getUserThumb(userDetail);
? ? ? ? ? ? emitter.onNext(bitmap);
? ? ? ? }
? ? ? ? //壓縮圖片
? ? ? ? for (int i = 0; i < bitmaps.size(); i++) {
? ? ? ? ? ? Bitmap bitmap = bitmaps.get(i);
? ? ? ? ? ? final Bitmap cbitmap = compressBitmap(bitmap);
? ? ? ? }
? ? ? ? emitter.onNext("壓縮圖片成功");
? ? ? ? //保存圖片
? ? ? ? for (int i = 0; i < bitmaps.size(); i++) {
? ? ? ? ? ? Bitmap bitmap = bitmaps.get(i);
? ? ? ? ? ? saveBitmap(bitmap);
? ? ? ? }
? ? ? ? emitter.onNext("保存圖片成功");
? ? }
}).subscribeOn(Schedulers.io())
? ? ? ? .observeOn(AndroidSchedulers.mainThread())
? ? ? ? .subscribe(new Consumer() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void accept(Object object) throws Exception {
? ? ? ? ? ? ? ? //Ui更新
? ? ? ? ? ? }
? ? ? ? });