美文网首页
Android RxJava 的应用场景

Android RxJava 的应用场景

作者: 虞_18bd | 来源:发表于2020-12-31 20:45 被阅读0次

    随着前两年的Rxjava的发展,响应式编程更像是一场风暴,席卷了大部分语言

    RxJava

    RxJS

    RxCpp

    RxGo

    等等各种Rx系列,俨然一片乐视贾老板生态化反的架势。

    下面就说明一下我在项目中对RxJava的应用,更确切点说应该是RxAndroid

    1.为什么要使用RxAndroid,它有哪些好处呢

    那我就告诉你,我最开始尝试使用RxAndroid,只是因为它看起来很酷。

    好吧,它也解决了Java异步线程回调的线程切换问题(其实也不算解决,只能说更方便操作了)

    emmm更多的是你要记住各种各样的操作符,其实你也并不需要特意记住,因为在像是kotlin,Java8又或是JS中,如fliter,map,foreach这种高阶函数的出场率还是很高的。那我这就总结我觉得的优势吧

    1.全新的编程风格,原本异步的任务回调被整理成了一堆对象,通过对对象的组合和管理,实现了无比优雅的异步任务协同。

    2.线程切换,还在为handler而觉得烦躁么,只要在subscribeOn和observeOn设定好线程,它就能轻松的在工作线程和UI线程之间进行切换。

    3.通用的高阶函数操作符,Rx系列与其说它是一种库,它更像一种生态,它是一种事件处理的框架,适用任何平台,减少了开发人员在各个平台切换的时间成本。

    2.废话不多说,直接看例子

    下面是每个android app开发都会碰上的场景

    用户注册账号 ————> 请求注册接口————>注册成功后————>请求登录————>自动登录 ———— >登录成功请求账户数据

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

    //LoginActivity.java
    
    // 点击注册按钮
    RxView.clicks(mDataBinding.submitBtn) // 这是RxView 它可以把点击事件转换成Observable
                    .to(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this))) // 这里是绑定页面的生命周期,防止页面被销毁时请求还在等待回调
                    .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);// 通过数据中心发送请求
            registerState.postValue(ERROR_CUSTOMER_SUCCESS_PASS);  // 通过校验
        }
    }
    
    //LoginRepository.java
    
        /**
         * 注册账号请求
         *
         * @param username 账户名
         * @param password 密码
         */
    public void registerReq(LifecycleOwner lifecycleOwner,String username, String password) {
        // 这里是通过Retrofit转换成的Flowable(背压)
        LoginRequestBuilder.registerFlowable(username, password)
                    .subscribeOn(Schedulers.io()) // 异步线程发出请求
                    .observeOn(AndroidSchedulers.mainThread()) // 主线程处理返回
                    .to(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner))) // 绑定页面生命周期,防止内存泄漏
                    .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() {
    
                        }
                    });
        }
    
    

    // 上面就是注册的大概流程,接下来就是酷炫的登录流程了,其实确实可以把注册+登录+请求数据合并在一起,但是为了可读性,我还是牺牲了一点点酷炫

    /**
     * 登录请求
     *
     * @param userName 账号
     * @param passWord 密码
     */
    public void loginReq(LifecycleOwner lifecycleOwner, String userName, String passWord) {
        LoginRequestBuilder.loginFlowable(userName, passWord)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())  // 这里通过flatMap把一次请求的结果转换成一次新的请求
                .flatMap((Function<BaseResponBean<LoginResponBean>,  Flowable<BaseResponBean<AccountInfoBean>>>) loginBean -> {
                    if (loginBean != null) { // 登录成功
                        Optional.ofNullable(loginBean.getData()).ifPresent(userInfo -> mUserInfo = userInfo); //                        保存返回的数据
                        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()));  // 抛出登录异常  不会继续链式调用
                        }
                    }
                    return Flowable.error(new ApiException(-1, "网络异常"));  // 抛出登录异常  不会继续链式调用
                })
                .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合并请求,具体各种高阶函数就不一一介绍了。

    相关文章

      网友评论

          本文标题:Android RxJava 的应用场景

          本文链接:https://www.haomeiwen.com/subject/djproktx.html