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;
}
}
};
}
}