Retrofit中的类型转换

在网络请求中由于各种业务需要,定义的接口入参、出参类型各不相同
以往做法都是在请求成功的回调方法中自行解析response的内容,写法不一又显得重复累赘。
而retrofit采用了2个接口来解决该问题。

retrofit中的2个类型转换接口
1、CallAdapter接口

public interface CallAdapter<R, T> {
		Type responseType();
		T adapt(Call<R> call);
		abstract class Factory {
			public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
			Retrofit retrofit);
		}
	}

responseType方法:
	你需要的返回类型
adapt方法:	
	将请求Call对象转换为Java的T泛型对象
Factory工厂负责创建CallAdapter的适配器,新创建的适配器实体类就得实现以上2个接口方法

2、Converter接口

public interface Converter<F, T> {
		@Nullable T convert(F value) throws IOException;
		abstract class Factory {
			public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
			Annotation[] annotations, Retrofit retrofit);
			
			public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
			Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit);
			
		}
	}

convert方法:
	将类型F转换为T,实现数据类型转换
Factory工厂中的方法分别负责创建请求和响应的转换器	

使用:

1、保存(set)
   提供addCallAdapterFactory方法把适配器创建者(工厂)存在callAdapterFactories变量中,这里将存放用户自己实现的工厂类及工厂所负责创建的适配器
   提供addConverterFactory方法把类型转换器创建者(工厂)存在converterFactories变量中,这里也存放着用户的相关实现类
2、获取(get)	
   提供nextCallAdapter方法获取CallAdapter接口对象,这里就是获取了第1步变量中的值
   提供nextRequestBodyConverter方法获取Converter接口对象,这里也是获取了第1步变量中的值
3、ServiceMethod类负责解析注册进来的注解
	提供createCallAdapter方法获取CallAdapter,这里就是通过第2步的方法获取
	提供createResponseConverter方法创建Converter,这里也是通过第2步的方法获取
	在parseAnnotations方法中,获取callAdapter的responseType类型,并传给Converter的工厂的方法,方便用户创建转换器
	如Gson的转换器便是这样创建的:  
	

public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
			Retrofit retrofit) {
			TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
			return new GsonResponseBodyConverter<>(gson, adapter);
		}
4、在Call的实现类OkHttpCall中通过代码
	T body = responseConverter.convert(catchingBody);将最初始的response转换成T(这样就得到了用户需要的数据类型)						
5、调用入口流程		
    用户通过create方法创建完请求之后(这里通注解方式把请求和响应的数据类型都注册给retrofit了),
	create的回调方法invoke就被调用了。(关于回调可参考[https://blog.csdn.net/u010082177/article/details/99311585](https://blog.csdn.net/u010082177/article/details/99311585))		
	在invoke回调方法中:
		return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
		调用loadServiceMethod方法完成对方法的注解解析
		调用invoke方法其实时调用了ServiceMethod的实现类HttpServiceMethod的invoke方法
		return callAdapter.adapt(new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
		调用adapter方法才真正调用了CallAdapter的实现类的方法,该方法的返回类型就是用户想要的类型
		参数new OkHttpCall把获取的convert适配器对象都传给了OkHttpCall,然后就获取到了第4步中的类型。

总结:

在碰到需要处理不同的数据类型转换时,可参考以上2个接口的设计
接口定义了一种能力,该能力在具体的实现类得以体现,而接口中的工厂只是按需来创建不同的实现类。	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值