Retrofit2学习之九:与RxJava结合

需求:实现用户登录,然后通过登陆返回的用户Id获取用户信息。

普通实现

创建业务请求接口

public interface Api {

    @POST("login/json")
    Call<ResponseResult> login(@Body UserParam param);

}

创建一个Retrofit的实例,然后利用Retrofit实例创建接口对象和调用接口方法

public void login(View view) {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(SERVER_ADDRESS)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    api = retrofit.create(Api.class);

    api.login(new UserParam("AppBlog.CN", "123456")).enqueue(new Callback<ResponseResult>() {
        @Override
        public void onResponse(Call<ResponseResult> call, Response<ResponseResult> response) {
            if (response.isSuccessful()) {
                int userId = response.body().getUserId();
                api.getUserInfoWithPath(userId).enqueue(new Callback<User>() {
                    @Override
                    public void onResponse(Call<User> call, Response<User> response) {
                        if (response.isSuccessful()) {
                            User user = response.body();
                            Toast.makeText(MainActivity.this, user.getUsername(), Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onFailure(Call<User> call, Throwable t) {
                        Log.i(TAG, "请求失败: " + t.getLocalizedMessage());
                    }
                });
            }
        }

        @Override
        public void onFailure(Call<ResponseResult> call, Throwable t) {
            Log.i(TAG, "登录失败: " + t.getLocalizedMessage());
        }
    });
}

缺点:代码繁琐,嵌套多不方便扩展

与RxJava结合

添加依赖

compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.2.3'

创建业务请求接口

public interface Api {

    @POST("login/json")
    Observable<ResponseResult> loginWithRx(@Body UserParam param);

}

创建一个Retrofit的实例,然后利用Retrofit实例创建接口对象和调用接口方法

//嵌套写法
public void loginWithRx(View view) {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(SERVER_ADDRESS)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();

    api = retrofit.create(Api.class);

    api.loginWithRx(new UserParam("AppBlog.CN", "123456")).subscribeOn(Schedulers.io()).subscribe(new Subscriber<ResponseResult>() {
        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {
            e.printStackTrace();
            Log.i(TAG, "登录失败: " + e.getLocalizedMessage());
        }

        @Override
        public void onNext(ResponseResult responseResult) {
            api.getUserInfoWithRx(responseResult.getUserId())
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Action1<User>() {
                        @Override
                        public void call(User user) {
                            Toast.makeText(MainActivity.this, user.getUsername(), Toast.LENGTH_SHORT).show();
                        }
                    });
        }
    });
}

优点:

  • 使用RxJava适配器 addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 可以实现返回Body自动转换为ResponseResult对象
  • 使用 subscribeOn(Schedulers.io())observeOn(AndroidSchedulers.mainThread()) 轻松实现IO线程和UI线程间的切换

缺点:代码嵌套仍然过多,不方便扩展

RxJava链式写法

创建业务请求接口

public interface Api {

    @GET("user/{id}")
    Observable<User> getUserInfoWithRx(@Path("id") int userId);

}

创建一个Retrofit的实例,然后利用Retrofit实例创建接口对象和调用接口方法

//链式写法
public void loginWithRxChain(View view) {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(SERVER_ADDRESS)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();

    api = retrofit.create(Api.class);

    api.loginWithRx(new UserParam("AppBlog.CN", "123456")).flatMap(new Func1<ResponseResult, Observable<User>>() {
        @Override
        public Observable<User> call(ResponseResult responseResult) {
            return api.getUserInfoWithRx(responseResult.getUserId());
        }
    }).doOnNext(new Action1<User>() {
        @Override
        public void call(User user) {
            //download avatar
        }
    }).doOnSubscribe(new Action0() {
        @Override
        public void call() {

        }
    }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<User>() {
        @Override
        public void call(User user) {
            Toast.makeText(MainActivity.this, user.getUsername(), Toast.LENGTH_SHORT).show();
        }
    });
}

优点:代码链式写法,结构清晰,扩展方便

上一篇 Retrofit2学习之八:服务端上传文件设计
下一篇 RxJava2学习之一:观察者模式
目录
文章列表
1 基于Java代码进行GPG加解密
基于Java代码进行GPG加解密
2
React Native学习之RN与iOS原生通信
React Native学习之RN与iOS原生通信
3
Android启动页黑屏及最优解决方案
Android启动页黑屏及最优解决方案
4
常用开发工具整理
常用开发工具整理
5
MySQL慢查询
MySQL慢查询
最新评论
一位WordPress评论者
一位WordPress评论者
2月12日
您好,这是一条评论。若需要审核、编辑或删除评论,请访问仪表盘的评论界面。评论者头像来自 Gravatar。