Retrofit2.0的使用

Retrofit2.0

一、添加依赖

compile 'com.squareup.retrofit2:retrofit:2.2.0'

二、简单使用

RetroFit使用步骤:

 1.定义一个接口(封装url地址和数据请求)
 2.实例化retrofit
 3.调用retrofit实例创建接口服务对象
 4.调用接口中的方法获取Call对象
 5.call对象请求(异步\同步请求)

2.1 定义接口

首先,需要定义baseUrl,定义接口时通过@GET/@POST标记发起get/post请求,@GET/@POST中填写baseUrl后的路径,访问的网络地址由baseUrl和@GET/@POST注解后的路径拼接组成,baseUrl在构造retrofit对象时给出。

下面是几种案例:

2.1.1 @Get 直接拼接地址

  • 1.标记为Get请求
  • 2.拼接地址,url里的参数为常量
  • 3.指定返回值为泛型类型是String的Call对象。因为Retrofit单独使用时,使用Call对象发起网络请求,所以这里指定返回值为Call对象。泛型值指定的是你希望的请求回调里response.body()的值。若为Call < ResponseBody >:ResponseBody responseBody = response.body();若为Call < String >:String str = response.body();
    注意:泛型类型需Retrofit添加转化器支持。具体参见:四、为Retrofit添加转化器支持(泛型类型)。
  • 4.请求方法名
2.1.2 @Get url里的包含变量,使用{type}占位

  • 1.使用{}标记这里是变量,userId为形参名
  • 2.指定Url里的形参变量
  • 3.指定传入参数类型为String
  • 4.指定传入参数的变量名

多个参数使用相同格式,并用“,”相隔。例如:

2.1.3 @Get 请求参数为一个键值对

  • 1.使用@Query标记为键值对
  • 2.键名
  • 3.传入的值名已经类型

备注:拼接的Url写到“?”前。

2.1.4 @Get 请求参数为多个键值对

  • 1.使用@QueryMap标记为多个键值对
  • 2.指定传入参数值
2.1.5 @Get 多种方式组合

2.1.6 @Get 下载图片

2.1.7 @Post 提交表单


2.1.8 @Post 上传单个文件

2.1.9 @Get 上传表单中的所有数据(表单数据+附件)


2.2 实例化retrofit

可以构造以下参数:


2.3 创建接口服务对象

IRetrofitView为2.1中定义Retrofit接口的类。


2.4 调用接口中的方法获取Call对象


2.5 call对象请求(异步\同步请求)

三、为Retrofit添加返回值支持

上文说道,Retrofit定义接口时,可以指定返回值为指定泛型类型的指定对象,这个指定对象的类型并不是随意指定的,需要在Retrofit里添加相应的CallAdapter。例如,若指定返回类型为Observable对象,需要添加RxJava2CallAdapterFactory。

3.1 添加RxJava2依赖

compile 'io.reactivex.rxjava2:rxjava:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'

3.2 Retrofit添加CallAdapter

3.3 Retrofit支持添加的Call类型

四、为Retrofit添加转化器支持

在Retrofit2的版本中没有默认的转换器,需要自己添加ConverterFactory。例如,项目使用Gson,需要添加支持Gson的依赖项。

4.1 添加Gson依赖

compile 'com.squareup.retrofit2:converter-gson:2.3.0'

4.2 Retrofit添加Converter

4.3 Retrofit支持添加的Converter类型

  • String类型支持:addConverterFactory(ScalarsConverterFactory.create())

备注:一个Retrofit对象只能添加一种支持。

五、其他问题

5.1 json解析报错

需要添加以下方法:

 /**
 * 防止Gson解析报错
 */
private static class SafeTypeAdapterFactory implements TypeAdapterFactory {

    @Override
    public TypeAdapter create(Gson gson, final TypeToken type) {
        final TypeAdapter delegate = gson.getDelegateAdapter(this, type);
        return new TypeAdapter() {

            @Override
            public void write(JsonWriter out, Object value) throws IOException {
                try {
                    delegate.write(out, value);
                } catch (IOException e) {
                    delegate.write(out, null);
                }
            }

            @Override
            public Object read(JsonReader in) throws IOException {
                try {
                    return delegate.read(in);
                } catch (IOException e) {
                    in.skipValue();
                    return null;
                } catch (IllegalStateException e) {
                    in.skipValue();
                    return null;
                } catch (JsonSyntaxException e) {
                    in.skipValue();
                    if (type.getType() instanceof Class) {
                        try {
                            return ((Class) type.getType()).newInstance();
                        } catch (Exception e1) {

                        }
                    }
                    return null;
                }
            }

        };
    }
}

5.1 定义OkHttpClient

详见文章:OkHttp的使用 三 定义OkHttpClient