Retrofit2.0+RxJava初步

之前看了StormZhang的网络请求哪家强, 里面有详细的主流网络请求框架对比,
最近在自己的项目中引入了Retrofit2.0, 同时配合使用RxJava,替换了原先OkHttp。

本文对于基本的实现做了总结,也有一些碰到的问题,以及Retrofit2.0相对1.0版本的一些变化

依赖项

compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.1.6'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:+'
compile 'com.squareup.retrofit2:adapter-rxjava:+'

可以看到, 除了RxAndroid, RxJava, Retrofit依赖,另外还有两个: converter-gson, adapter-rxjava. 下面会做详细介绍。

定义请求接口

通过注解的方式,为每个请求声明请求的类型(Get, Post, Delete ...) , 地址, 以及参数等, 如下:

public interface CommentService{
    @GET("shots/{id}/comments")
    Observable getComments(@Path("id") int id,
                                      @Query("page") String page);
}

这里需要注意的是, 2.0中地址格式的变化:

Correct: Base URL: http://example.com/api/
Endpoint: foo/bar/ Result: http://example.com/api/foo/bar/

而1.0中Base URL最后的“/”是在Endpoint中。

创建Retrofit实例

Retrofit提供了Builder和工厂模式来创建对应的请求实例,如下:

public static  T createRetrofitService(final Class clazz) {

    String GET_API_URL = "https://api.dribbble.com/v1/";

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(GET_API_URL)
            .addConverterFactory(GsonConverterFactory.create()) 
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())  
            .build();
    return retrofit.create(clazz);
}

我们可以看到, 在build过程中,增加了GsonConverterFactory和RxJavaCallAdapterFactory, 分别是在上述引用依赖时候的内容, 下面我们来看看Retrofit提供的这两个工厂类:

  1. GsonConverterFactory
    顾名思义,它是一个Json数据转化类,其中Gson是目前应用最广泛的Json解析库,所以Retrofit引入它就是为了将数据转化封装到内部实现,也减少了我们的工作量。
    当然1.0的Retrofit还没有引入, 我们会看到1.0是使用RestAdapter来实现请求结果转化的,下面是一段官方解释:

But in Retrofit 2.0, Converter is not included in the package anymore. You need to plug a Converter in yourself or Retrofit will be able to accept only the String result. As a result, Retrofit 2.0 doesn't depend on Gson anymore.
If you want to accept json result and make it parse into DAO, you have to summon Gson Converter as a separate dependency.
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2' And plug it in through addConverterFactory. Please note that RestAdapter is now also renamed to Retrofit.

  1. RxJavaCallAdapterFactory
    这个类是为了与RxJava衔接而提供的, 如果不添加这个实现, 直接使用RxJava的观察者模式,会得到如下报错:
    Unable to create call adapter for class

进一步封装

通过上述“定义接口”, “创建实例”, 我们已经可以实现一个完整的请求,并将结果输出, 但是, 这样的请求并不是非常灵活, 例如,如何为每个请求中添加header信息?(我们在项目中经常把token作为每次请求的必带参数),如果按照上述方法,得在每个接口中申明header参数,显然是不太合理。
Retrofit当然也会考虑这些问题, 可以实现自定义http客户端,我们在builder之前进行自定义,代码:

public static  T createRetrofitService(final Class clazz) {

    String GET_API_URL = "https://api.dribbble.com/v1/";
    final OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    httpClient.addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request original = chain.request();

            Request.Builder builder = original.newBuilder()
                    .method(original.method(), original.body())
                    //添加请求头部信息
                    .header("Authorization", "Bearer " + ServiceConfig.ACCESS_TOKEN);

            return chain.proceed(builder.build());
        }
    });

    OkHttpClient okHttpClient = httpClient.build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(GET_API_URL)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();
    return retrofit.create(clazz);
}

这样,就实现了每次请求都带了Header信息。以此为例, 我们还可以进一步实现请求缓存等功能, 后续再更新...
另外, RxJava的监听线程等方法也可以封装:

public static  void toSubscribe(Observable o, Subscriber s) {
    o.subscribeOn(Schedulers.io())
            .unsubscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(s);
}

完成请求

有了以上的封装,以下是我在UI层调用网络请求的代码:

ServiceFactory.toSubscribe(getObservable(), new Subscriber() {
    @Override
    public void onCompleted() {

    }

    @Override
    public void onError(Throwable e) {
        requestFailed();
    }

    @Override
    public void onNext(Shot[] resultList) {
        requestSuccess(resultList);
    }
});

Observable getObservable() {
    return ServiceFactory.createRetrofitService(
            DribService.ShotService.class).getShots(String.valueOf(mPage), mQueryMap);
}

总结

引入了Retrofit2.0 + RxJava, 确实使整个项目结构更加清晰, 而且也省去了原先OkHttp封装的工作。下面是我自己项目的地址,里面有更加详细的内容,后续也会进一步做一些更新,例如请求缓存等内容。
https://github.com/binqiangsun/DribbblApp
刚刚接触Retrofit,如果上述有错误的地方,欢迎交流指正,谢谢~

你可能感兴趣的:(Retrofit2.0+RxJava初步)