Android RxJava 的應用場景

隨著前兩年的Rxjava的發(fā)展,響應式編程更像是一場風暴,席卷了大部分語言

RxJava

RxJS

RxCpp

RxGo

等等各種Rx系列,儼然一片樂視賈老板生態(tài)化反的架勢。

下面就說明一下我在項目中對RxJava的應用,更確切點說應該是RxAndroid

1.為什么要使用RxAndroid,它有哪些好處呢

那我就告訴你,我最開始嘗試使用RxAndroid,只是因為它看起來很酷。

好吧,它也解決了Java異步線程回調(diào)的線程切換問題(其實也不算解決,只能說更方便操作了)

emmm更多的是你要記住各種各樣的操作符,其實你也并不需要特意記住,因為在像是kotlin,Java8又或是JS中,如fliter,map,foreach這種高階函數(shù)的出場率還是很高的。那我這就總結(jié)我覺得的優(yōu)勢吧

1.全新的編程風格,原本異步的任務回調(diào)被整理成了一堆對象,通過對對象的組合和管理,實現(xiàn)了無比優(yōu)雅的異步任務協(xié)同。

2.線程切換,還在為handler而覺得煩躁么,只要在subscribeOn和observeOn設定好線程,它就能輕松的在工作線程和UI線程之間進行切換。

3.通用的高階函數(shù)操作符,Rx系列與其說它是一種庫,它更像一種生態(tài),它是一種事件處理的框架,適用任何平臺,減少了開發(fā)人員在各個平臺切換的時間成本。

2.廢話不多說,直接看例子

下面是每個android app開發(fā)都會碰上的場景

用戶注冊賬號 ————> 請求注冊接口————>注冊成功后————>請求登錄————>自動登錄 ———— >登錄成功請求賬戶數(shù)據(jù)

下面就是用RxView + RxAndroid + Retrofit 的處理流程

//LoginActivity.java

// 點擊注冊按鈕
RxView.clicks(mDataBinding.submitBtn) // 這是RxView 它可以把點擊事件轉(zhuǎn)換成Observable
                .to(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this))) // 這里是綁定頁面的生命周期,防止頁面被銷毀時請求還在等待回調(diào)
                .subscribe(unit -> mViewModel.register(mDataBinding.registerUserNameEdt.getText().toString().trim()
                        , mDataBinding.registerPasswordEdt.getText().toString().trim()
                        , mDataBinding.repeatRegisterPasswordEdt.getText().toString().trim()));// 注冊方法



//RegisterViewModel.java

public void register(String userName, String passWord, String repeatPassword){
     if(checkInfo(userName, passWord, repeatPassword)){  // 通過格式校驗
        loginRepository.registerReq(lifecycleOwner, userName, passWord);// 通過數(shù)據(jù)中心發(fā)送請求
        registerState.postValue(ERROR_CUSTOMER_SUCCESS_PASS);  // 通過校驗
    }
}

//LoginRepository.java

    /**
     * 注冊賬號請求
     *
     * @param username 賬戶名
     * @param password 密碼
     */
public void registerReq(LifecycleOwner lifecycleOwner,String username, String password) {
    // 這里是通過Retrofit轉(zhuǎn)換成的Flowable(背壓)
    LoginRequestBuilder.registerFlowable(username, password)
                .subscribeOn(Schedulers.io()) // 異步線程發(fā)出請求
                .observeOn(AndroidSchedulers.mainThread()) // 主線程處理返回
                .to(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner))) // 綁定頁面生命周期,防止內(nèi)存泄漏
                .subscribe(new DisposableSubscriber<BaseResponBean>() {
                    @Override
                    public void onNext(BaseResponBean registerBean) {
                        if (registerBean != null) {
                            LiveEventBus.get(RequestTags.REGISTER_REQ, BaseResponBean.class)
                                    .post(new BaseResponBean<>(registerBean.getCode(), registerBean.getMessage()));         // 頁面要處理的邏輯(登錄返回)
                        }
                    }

                    @Override
                    public void onError(Throwable t) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

// 上面就是注冊的大概流程,接下來就是酷炫的登錄流程了,其實確實可以把注冊+登錄+請求數(shù)據(jù)合并在一起,但是為了可讀性,我還是犧牲了一點點酷炫

/**
 * 登錄請求
 *
 * @param userName 賬號
 * @param passWord 密碼
 */
public void loginReq(LifecycleOwner lifecycleOwner, String userName, String passWord) {
    LoginRequestBuilder.loginFlowable(userName, passWord)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())  // 這里通過flatMap把一次請求的結(jié)果轉(zhuǎn)換成一次新的請求
            .flatMap((Function<BaseResponBean<LoginResponBean>,  Flowable<BaseResponBean<AccountInfoBean>>>) loginBean -> {
                if (loginBean != null) { // 登錄成功
                    Optional.ofNullable(loginBean.getData()).ifPresent(userInfo -> mUserInfo = userInfo); //                        保存返回的數(shù)據(jù)
                    if (loginBean.getMessage() != null) {
                        LiveEventBus.get(RequestTags.LOGIN_REQ, BaseResponBean.class)
                                .post(new BaseResponBean<>(loginBean.getCode(), loginBean.getMessage()));         // 頁面要處理的邏輯(注冊返回)
                    }
                    if (loginBean.getCode() == 200
                            && loginBean.getData() != null
                            && loginBean.getData().getToken() != null
                            && loginBean.getData().getRoomservice_sign() != null
                            && loginBean.getData().getRoomservice_sign().getUserID() != null) {
                        setToken(loginBean.getData().getToken());  //                                              Token 保存到本地 用于后期請求鑒權
                        setUserId(loginBean.getData().getRoomservice_sign().getUserID());//                        UserId 保存到本地 當前登錄的賬號
                        initMLVB();//                                                                              初始化直播SDK
                        return LoginRequestBuilder.accountFlowable(getUserId(), getToken()); //                             請求賬戶信息
                    } else {
                        return Flowable.error(new ApiException(loginBean.getCode(), loginBean.getMessage()));  // 拋出登錄異常  不會繼續(xù)鏈式調(diào)用
                    }
                }
                return Flowable.error(new ApiException(-1, "網(wǎng)絡異常"));  // 拋出登錄異常  不會繼續(xù)鏈式調(diào)用
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .to(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner)))
            .subscribe(new DisposableSubscriber<BaseResponBean<AccountInfoBean>>() {
                @Override
                public void onNext(BaseResponBean<AccountInfoBean> accountBean) {
                    if (accountBean != null && accountBean.getCode() == 200) {  // 查詢賬戶信息返回
                        if (accountBean.getData() != null) {
                            if (accountBean.getData().getAvatar() != null)
                                loginSaveBean.setmUserAvatar(accountBean.getData().getAvatar());  //      保存用戶頭像信息
                            if (accountBean.getData().getNickname() != null)
                                loginSaveBean.setmUserName(accountBean.getData().getNickname()); //       用戶稱呼
                            if (accountBean.getData().getFrontcover() != null)
                                loginSaveBean.setmCoverPic(accountBean.getData().getFrontcover());//      直播封面?
                            if (accountBean.getData().getSex() >= 0) {
                                loginSaveBean.setmSex(accountBean.getData().getSex());//                  用戶性別
                            }
                        }
                    }
                }

                @Override
                public void onError(Throwable t) {
                    if (t instanceof ApiException) {
                        Log.e("TAG", "request error" + ((ApiException) t).getStatusDesc());
                    } else {
                        Log.e("TAG", "request error" + t.getMessage());
                    }
                }

                @Override
                public void onComplete() {

                }
            });
}

以上就是把兩個鏈式請求的接口通過flatmap鏈接,或者通過zip合并請求,具體各種高階函數(shù)就不一一介紹了。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容