Android RxJava与Retrofit怎么结合使用

蜗牛 互联网技术资讯 2023-03-13 86 0

本篇内容介绍了“Android RxJava与Retrofit怎么结合使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

添加依赖

compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'io.reactivex.rxjava2:rxjava:2.x.y'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'

添加依赖本并不想多说,我想大家都知道,但是对于刚接触这些知识的时候我想有没有人在看网上的文章时会觉得有些依赖是在哪找到并添加的呢?例如:com.squareup.retrofit2:converter-gson:2.3.0我们要添加一个GsonConverter的依赖。对于刚接触这些知识和不经常逛GitHub的人来说会不会一脸懵逼呢?不管会不会,反正我第一次接触的时候确实懵逼了下。这里给那些懵逼过的人提示下,我们可以通过打开GitHub上项目的子文件查看到相应的依赖。比如GitHub上Retrofit项目中:retrofit/retrofit-converters/gson/这个路径下就可以查看到相应的GsonConverter的依赖。

封装Retrofit(单例模式)

public class HttpRequest {
    public static final long CONNECTTIME = 30000;
    public static final String BASE_URL = "http://jxhdapi.ooowin.com/";
    private  ApiService apiService;
    public HttpRequest() {
        //添加日志拦截器
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.d("TAG", "==========" + message);
            }
        }).setLevel(HttpLoggingInterceptor.Level.BODY);
        //获取OkHttpClient
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(CONNECTTIME, TimeUnit.MICROSECONDS)
                .readTimeout(CONNECTTIME,TimeUnit.MICROSECONDS)
                .writeTimeout(CONNECTTIME,TimeUnit.MICROSECONDS)
                .addInterceptor(interceptor)
                .addNetworkInterceptor(new HttpHeaderInterceptor())
                .build();
        //初始化Retrofit
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(client)
                .build();
        apiService = retrofit.create(ApiService.class);
    }
    //  创建单例
    private static class SingletonHolder {
        private static final HttpRequest INSTANCE = new HttpRequest();
    }
    public static ApiService getApi(){
        return SingletonHolder.INSTANCE.apiService;
    }
}

这里我们可以看到添加了两个拦截器:日志拦截器和网络请求Header拦截器,我们都知道对于Retrofit我们是可以直接通过GsonConverter转换成实体类的,但有的时候我们又想去获取它的json数据进行查看,这个时候我们就可以通过添加日志拦截器实现,但一定要给它设置setLevel方法,设置不同的属性打印出来的数据是不一样的。至于添加Header拦截器我想大家都应该知道,正常工作中接口所需要的Header都是相同的,所以我们要进行统一添加:

public class HttpHeaderInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Request build = request.newBuilder()
//                .addHeader("","")   添加header
                .build();
        return chain.proceed(build);
    }
}

封装实体类

{
    "code": 1,
    "msg": "操作成功",
    "data": {······}
}

通常我们从服务端拿到的json数据就像上面那样,有些返回的字段内容格式是固定的,比如:code和msg。有些则是不确定,如:data。这个时候我们就需要对其进行二次处理了,我们可以写一个基类:

public class BaseBean<T> {
    private int code;
    private String msg;
    private T data;
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
}

利用泛型来表示data中的不确定格式的数据,这里用一个获取全国所有省的数据接口进行测试:

public interface ApiService {
    //获取省列表
    @GET("common/areas")
    Flowable<BaseBean<List<Province>>> province();
}

实体类封装好后我们可以进行一下测试:

HttpRequest.getApi()
            .province()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<BaseBean<List<Province>>>() {
                @Override
                public void onSubscribe(Subscription s) {
                }
                @Override
                public void onNext(BaseBean<List<Province>> listBaseBean) {
                }
                @Override
                public void onError(Throwable t) {
                }
                @Override
                public void onComplete() {
                }
            });
}

通过上面的代码我们不难看出这是经过封装后的效果,但是我们会发现这样的请求我们难道每次都要去添加调度器和重写Subscriber的几个方法吗?那岂不还是很繁琐。是的,接下来我们就对这些进行封装。

使用compose操作符

public class SchedulersHelper implements FlowableTransformer{
    @Override
    public Publisher apply(Flowable upstream) {
        return  upstream.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }
}

使用compose操作符可以直接对当前Flowable进行操作,所以我们自然可以把切换线程的操作加入这里。接下来就是Subscriber进行封装了。

封装Subscriber

public abstract class MySubscriber<T> implements Subscriber<T>{
    @Override
    public void onSubscribe(Subscription s) {
        s.request(Long.MAX_VALUE);
        showLoading();
    }
    @Override
    public void onNext(T t) {
        //code为1代表服务器返回成功的数据
        if (((BaseBean)t).getCode() == 1) {
            //成功后返回data数据进行处理即可
            onSuccess((T) ((BaseBean) t).getData());
        }else {
            //处理服务器返回错误code
        }
    }
    @Override
    public void onComplete() {
        finishLoading();
    }
    @Override
    public void onError(Throwable t) {
        finishLoading();
        //处理网络异常
        Log.d("TAG","=========" + t);
    }
    protected abstract void onSuccess(T t);
    protected abstract void showLoading();
    protected abstract void finishLoading();
}

如上所示,我们根据服务端返回的code判断是否成功,将data数据传出去。服务器返回的错误码和网络请求错误我们都可以统一在这里进行处理。然后我们再去测试接口。

测试

HttpRequest.getApi().province()
        .compose(new SchedulersHelper())
        .subscribe(new MySubscriber() {
            @Override
            protected void onSuccess(Object o) {
            }
            @Override
            protected void showLoading() {
            }
            @Override
            protected void finishLoading() {
            }
        });

可以的看到操作流程已经变的很简单了,对于showLoading()finishLoading()这两个方法我们可以不需要放在这里面,这个是我方便测试便将其写在里面了。

“Android RxJava与Retrofit怎么结合使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注蜗牛博客网站,小编将为大家输出更多高质量的实用文章!

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:niceseo99@gmail.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

评论

有免费节点资源,我们会通知你!加入纸飞机订阅群

×
天气预报查看日历分享网页手机扫码留言评论Telegram