-
線程切換->
subscribeOn
和observeOn
Observable.just(1,2,3,4) .doOnNext { println("parade訂閱observeOn${Thread.currentThread().name}") //當subscribeOn在Schedulers.io()時 打印parade訂閱observeOnRxCachedThreadScheduler-1 //當subscribeOn在AndroidSchedulers.mainThread()時 打印parade訂閱observeOnmain } .observeOn(AndroidSchedulers.mainThread()) .doOnNext{ println("parade第一次observeOn${Thread.currentThread().name}")//parade第一次observeOnmain println("parade value is $it") } .observeOn(Schedulers.io()) .map { it * 3 println("parade第二次observeOn${Thread.currentThread().name}")//parade第二次observeOnRxCachedThreadScheduler-2 } .observeOn(AndroidSchedulers.mainThread()) .doOnNext{ println("parade第三次observeOn${Thread.currentThread().name}")//parade第三次observeOnmain } .subscribeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe()
由實例代碼可以看出
observeOn
指定的是它之後的操作所在的線程,而subscribeOn
指定產生訂閱時的線程,另外這樣做的好處是給用戶的的體驗是用戶感覺不到多次請求,也就是說如果要顯示加載Dialog,那麼從請求登錄開始顯示dialog到請求用戶信息結束dialog消失,所以用戶才感覺不到。從訂閱到整個請求鏈結束是一個完整的過程 -
操作符flatMap->用來把一個Observable轉成另外一個Observable
-
示例場景->登錄:先調用登錄接口,登錄成功後保存返回的token並接着調用獲取個人信息的接口
-
代碼實例
ApiService.getUserApi().loginWithMobile(etLoginAccount.getText().toString() , EncryptUtils.encryptMD5ToString(etLoginPwd.getText().toString().trim()).toLowerCase() , etLoginCode.getText().toString().trim()) .observeOn(AndroidSchedulers.mainThread())//這裏不可少,請求登錄用的是subscribeOn的io線程,登錄請求後切到主線程保存token或者刷新登錄驗證碼 .doOnNext(new Consumer<StringModel>() { @Override public void accept(StringModel stringModel) throws Exception { //登錄成功 app.getDataCenter().setToken(stringModel.getValue()); SPUtils.getInstance().put(SP_NAME_KEY, etLoginAccount.getText().toString().trim()); SPUtils.getInstance().put(SP_PWD_KEY,etLoginPwd.getText().toString().toString()); } }) .doOnError(new Consumer<Throwable>() { @Override public void accept(Throwable throwable) throws Exception { //登錄失敗,刷新二維碼,線程由上面的observeOn指定,是在主線程,因此可以更新UI etLoginCode.setText(""); requestPhotoCode(); } }) .observeOn(Schedulers.io())//處理完登錄接口後,再去調用請求個人信息接口 .flatMap(new Function<StringModel, ObservableSource<UserModel>>() { @Override public ObservableSource<UserModel> apply(StringModel stringModel) throws Exception { return ApiService.getUserApi().getUserInfo(); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseObserver<UserModel>(mContext, true) { @Override public void onNext(UserModel userModel) { //緩存用戶信息 app.getDataCenter().setUserModel(userModel); jumpActivity(MainActivity.class); } });
另外一個場景->上傳圖片,需要支持用戶同時上傳多張,但是接口只允許每次上傳一張
Observable.fromIterable(parts) .flatMap(new Function<MultipartBody.Part, ObservableSource<Object>>() { @Override public ObservableSource<Object> apply(MultipartBody.Part part) throws Exception { return ApiService.getProjectApi().uploadFile(part,Constant.orderAttach); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseObserver<Object>(mContext,true,"上傳中") { @Override public void onNext(Object o) { TLog.e("上傳成功"); String attachUrl = (String) ((LinkedTreeMap) o).get("value"); if (selectAdapter.getData().size() == Constant.orderAttachMaxSelect) { selectAdapter.getData().get(Constant.orderAttachMaxSelect - 1).setItemType(ImageVo.IMAGE); selectAdapter.getData().get(Constant.orderAttachMaxSelect - 1).setImageUrl(attachUrl); selectAdapter.notifyItemChanged(Constant.orderAttachMaxSelect - 1); } else { selectAdapter.addData(selectAdapter.getData().size() - 1, new ImageVo(ImageVo.IMAGE, attachUrl)); } if (selectAdapter.getData().size() == Constant.orderAttachSpan + 1) { new Handler().post(new Runnable() { @Override public void run() { nestScrollView.fullScroll(NestedScrollView.FOCUS_DOWN);//滾動到底部 } }); } attacheString = getAttachesString(selectAdapter.getData()); previewImages = getPreviewList(attachUrl); } });
-
-
操作符merge->用來合併兩個沒有關聯的請求
-
示例場景,有些界面展示的數據需要通過兩個不相關的接口獲得,因此可以同時進行請求,如果不使用類似merge的合併操作符,那麼給用戶的直觀是進行了兩次請求(如果要顯示dialog,那兩個請求的dialog是獨立的),使用merge就可以使用一個dialog
-
示例代碼
Observable<Feedback> feedbackInfoByAdviceId = NetWork.getOaService().getFeedbackInfoByAdviceId(themeId); Observable<AdviceTheme> adviceThemeById = NetWork.getOaService().getAdviceThemeById(themeId); Subscription subscription = Observable.merge(feedbackInfoByAdviceId,adviceThemeById) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseSubscriber<Object>(FeedBackDetailActivity.this){ @Override public void onNext(Object o) { //因爲兩個Observable返回的數據類型不一致,所以這裏要用Object接收並進行類型判斷 if (o instanceof Feedback){ tvFeedContent.setText(((Feedback)o).getContent()); }else if (o instanceof AdviceTheme){ AdviceTheme a = (AdviceTheme) o; tvThemeTitle.setText(a.getTitle()); CommonUtils.parseHtml(tvThemeContent,a.getContent()); } } });
-
Rxjava使用,沒有理論只有實戰
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.