1遇到問(wèn)題:
我們?cè)谶^(guò)長(zhǎng)的時(shí)間里,習(xí)慣了以往事情一步步的處理,這里我講的一步步的處理,指的是一系列的事件分步進(jìn)行叽粹,比如有如下需求,進(jìn)入activity之后需要立馬進(jìn)行如下操作:
先獲取用戶列表》》界面顯示用戶列表
獲取每個(gè)用戶的詳細(xì)信息》》將列表item設(shè)置為可點(diǎn)擊
獲取每個(gè)用戶的頭像》》列表中的用戶頭像顯示出來(lái)
對(duì)于用戶的頭像進(jìn)行壓縮》》輸出壓縮成功日志到控制臺(tái)
將壓縮后的頭像存儲(chǔ)》》輸出保存成功日志到控制臺(tái)
很明顯却舀,這一系列的事件如果按照以往的子線程調(diào)度虫几,然后handler切換更新ui,必定會(huì)使代碼變得冗長(zhǎng)而那一閱讀禁筏,代碼的縮進(jìn)也將像進(jìn)入了地獄般持钉,有人會(huì)說(shuō),以上步驟可以通過(guò)服務(wù)器返回足夠恰當(dāng)?shù)臄?shù)據(jù)一步完成篱昔。其實(shí)這里僅僅做一個(gè)例子每强,況且有些情況,服務(wù)端人員并不能溝通到的州刽,比如你需要調(diào)用第三方服務(wù)的接口空执,他們不會(huì)為了讓你方便一些就去對(duì)他們整個(gè)架構(gòu)大動(dòng)干戈的;
2穗椅,問(wèn)題思考:
既然傳統(tǒng)的方式看起來(lái)很麻煩辨绊,那么有沒(méi)有解決方法?如果目前我們不知道有Rxjava這個(gè)東西匹表,讓我們自己去封裝一個(gè)處理類似需求的解決方案該怎么辦门坷?我會(huì)思考將所有的處理都放到一個(gè)線程中去,然后在每一步結(jié)束的時(shí)候通過(guò)handler更新ui袍镀,類似如下偽代碼:
new Thread(new Runnable() {
? ? @Override
? ? public void run() {
? ? ? ? //獲取用戶列表
? ? ? ? List users = getUserList();
? ? ? ? mHander.post(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? //更新ui
? ? ? ? ? ? ? ? showUserList();
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? //獲取每個(gè)用戶詳情
? ? ? ? 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);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? }
? ? ? ? //獲取每個(gè)用戶的頭像
? ? ? ? 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("保存圖片成功");
? ? ? ? ? ? }
? ? ? ? });
? ? }
});
這樣做似乎還算簡(jiǎn)潔(其中有許多不合理的地方默蚌,比如圖片的一些列處理可以一個(gè)循環(huán)搞定,這里僅僅做一特例苇羡,不必深究)绸吸,也解決了地獄似得回調(diào),但似乎需要優(yōu)化的地方超級(jí)多:
?1设江,線程的創(chuàng)建與管理锦茁,代碼執(zhí)行線程的指定
?2,線程的切換
?3叉存,代碼編寫(xiě)麻煩
?4码俩,數(shù)據(jù)流處理很不完善
3,基于以上問(wèn)題的解決:
于是官方出品了自帶線程管理歼捏,線程切換稿存,鏈?zhǔn)阶兂晒话晟茢?shù)據(jù)操作符的Rxjava,如果帶著以上問(wèn)題再去審視Rxjava會(huì)好理解的多吧挠铲,那么我們?nèi)绻凑誖xjava的方式實(shí)現(xiàn)以上代碼是什么樣子的呢?偽代碼如下:
Observable.create(new ObservableOnSubscribe() {
? ? @Override
? ? public void subscribe(ObservableEmitter emitter) throws Exception {
? ? ? ? //獲取用戶列表
? ? ? ? List users = getUserList();
? ? ? ? emitter.onNext(users);
? ? ? ? //獲取每個(gè)用戶詳情
? ? ? ? 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);
? ? ? ? }
? ? ? ? //獲取每個(gè)用戶的頭像
? ? ? ? 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更新
? ? ? ? ? ? }
? ? ? ? });