美文网首页
RxJava 与 Retrofit 搭配的链式调用

RxJava 与 Retrofit 搭配的链式调用

作者: 虚心学习的小来子 | 来源:发表于2019-02-06 16:38 被阅读0次

    准备工作

    导入相关的依赖库,不要忘记导入 RxAndroid 的库

    // 开头的两个是两个适配器的依赖,根据自己的需求加,官网还有更多适配器的选择
    implementation 'com.squareup.retrofit2:converter-scalars:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
    

    使用场景分析

    在平时的安卓开发中,我们遇到像注册和登录这两个网络请求的时候,有时候会有这样的需求,我注册完了就紧接着要登录,通常遇到这钟情况的时候,我们都会选择在注册请求的回调当中接着去登录,这样子感觉还可以接受,只会有一层的嵌套,但是如果连续的请求更多的时候,就会在写代码的时候发现嵌套的层次太多了,代码的逻辑不容易读懂。
    这个时候如果我们使用的是 Rxjava 的时候,就会发现一连串的逻辑从头写到尾,思路十分的清楚,代码也很好读,当然 Rxjava 本身还是需要大家花一定得时间去学习,在这里我推荐一个大神的教程,看他的教程再搭配自己的使用的话就会很有收获,大神博客,他把 Observable 和 Observer 比喻为水管,形容的很贴切,对没有学过 Rxjava1 的人也很友好。

    先上代码

    public interface LoginInterface {
    
        @GET("***")
        Call<LoginBean> login(@Query("StudentID") String studentId, @Query("Password") String password, @Query("**") String param1, @Query("**") String param2);
            
        @GET("***")
        Observable<WeixinConnectBean> getUserInfo(@Query("StudentID") String studentId, @Query("**") String param1, @Query("**") String param2);
    
    }
    
    Retrofit retrofit = new Retrofit.Builder()
                        .addConverterFactory(ScalarsConverterFactory.create())
                        .addConverterFactory(GsonConverterFactory.create())
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                        // 换成你自己的URL
                        .baseUrl("********************")
                        .build();
    
    LoginInterface mLoginInterface = retrofit.create(LoginInterface.class);
    

    上面的这些代码和我们直接使用 Retrofit 来进行网络请求没有任何区别,但是 Retrofit 可以和 Rxjava 搭配进行网络请求,当然这里还忘了介绍 Rxjava 的另一个优点,就是线程切换十分方便,可以在下面的代码里面体现出来,让我们接着看下面的代码。

                mLoginInterface
                        .login_1(studentId, password, String.valueOf(currentTime), md5Str.substring(3, 18).toUpperCase())
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .doOnNext(new Consumer<LoginBean>() {
                            @Override
                            public void accept(LoginBean loginBean) throws Exception {
    
                                if (loginBean.getCode() != 1) {
                                    AlertDialog builder = new AlertDialog.Builder(LoginActivity.this)
                                    .setMessage(loginBean.getMsg())
                                    .setTitle("提示!")
                                    .setPositiveButton("我知道了", null)
                                    .create();
                                    builder.show();
                                    dialog.cancel();
                                    loginButton.setClickable(true);
                                }
                                Log.d(TAG, "登录成功!");
                                Log.d(TAG, "" + loginBean.getCode());
    
                            }
                        })
                        .doOnError(new Consumer<Throwable>() {
                            @Override
                            public void accept(Throwable throwable) throws Exception {
    
                                loginButton.setClickable(true);
                                Log.d(TAG, "调用失败");
    
                            }
                        })
                        .observeOn(Schedulers.io())
                        .flatMap(new Function<LoginBean, Observable<WeixinConnectBean>>() {
                            @Override
                            public Observable<WeixinConnectBean> apply(LoginBean loginBean) throws Exception {
    
                               if (loginBean.getCode() != 1) {
                                   mDisposable.dispose();
                               }
    
                               long currentTime = System.currentTimeMillis();
                               String md5Str = Md5Util.md5(KEY + currentTime);
                               return mLoginInterface.getUserInfo(studentId, String.valueOf(currentTime), md5Str.substring(3, 18).toUpperCase());
    
                            }
                        })
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Observer<WeixinConnectBean>() {
                            @Override
                            public void onSubscribe(Disposable d) {
                                mDisposable = d;
                            }
    
                            @Override
                            public void onNext(WeixinConnectBean response) {
    
                                getCourseData(studentId, password);
                                progressAnimator.start();
    
                                loginButton.setClickable(true);
    
                                String userName = response.getStuName();
                                String major = response.getMajor();
                                SharePreferenceLab.getInstance().setUsername(LoginActivity.this, userName);
                                SharePreferenceLab.getInstance().setMajor(LoginActivity.this, major);
    
                            }
    
                            @Override
                            public void onError(Throwable e) {
    
                                Log.d(TAG, "调用失败");
                                Toast.makeText(LoginActivity.this, "登录失败", Toast.LENGTH_SHORT).show();
                                dialog.cancel();
                                loginButton.setClickable(true);
    
    
                            }
    
                            @Override
                            public void onComplete() {
    
                            }
                        });
    

    大家可能第一反应会觉得代码不是很简洁,甚至有点不好理解,但是但凡大家对 Rxjava 有一定的掌握,都会觉得这样写很容易理解,特别是链接的请求更加多的时候,优势越发明显。

    链式请求的难点

    我觉得链式请求最需要注意的两个点一个是操作符的使用,另一个就是中断请求。我们接下来来分析这两个点。

    FlatMap 操作符的使用

    在这种情况下我们选择使用 Rxjava 的 FlatMap 操作符,这样子我们就可以将上一个请求返回的结果转换成下一个请求,这样就可以接着进行下一个请求了,根据上面的例子,我们需要实现一个 Function<LoginBean, Observable<WeixinConnectBean>>() 这个类里的 apply 这个方法,最后返回的一个 Observable,也就是另一个请求,在这里我们返回的是 mLoginInterface.getUserInfo(studentId, String.valueOf(currentTime), md5Str.substring(3, 18).toUpperCase()) ,当然这里还要注意一点,之前我们切换了线程到了主线程,这里我们需要回到 io 线程进行网络请求,但是这里还是用的是 observeOn 来切换线程。

    中断请求

    这里我们就要用 Rxjava 里面的一个新的东西叫作 Disposable,我们通过它来中止请求,这一点在我之前那个大神介绍的文章里面介绍的很仔细,他在里面比喻说相当于切断了上下游的联系,但是我们在哪里获取的 Disposable 的呢,大家看最后面的代码会发现,我们在订阅的时候,会先调用 onSubscribe 这个方法,这个方法的参数里面会给我们一个 Disposable 的引用,我们持着这个引用在需要中断的时候调用 dispose 方法,就会中止请求。

    总结

    当然 Rxjava 的操作符远不止这么一些,在以后还是会结合使用场景来进行分析,相信使用多了就会了解 Rxjava 的便利性。

    相关文章

      网友评论

          本文标题:RxJava 与 Retrofit 搭配的链式调用

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