OkHttp3 由于其易于拓展、灵活配置同时缓存策略的通用性、连接复用的高性能,已经基本成为目前安卓开发者使用率最高的“基础网络框架”。
之所以强调“基础网络框架”,是因为现在市面上有许多基于 OkHttp3 再次封装的网络请求库,其中比较著名的是 Retrofit。
Retrofit 独特的设计使得使用它发起网络请求就像服务端写接口一样,先定义一个 Service 然后直接调用方法即可,不用自己创建实现。
另外 Retrofit 可以和 Gson RxJava 无缝结合,这让它的使用更加方便。
接下来我们将从 Retrofit 的使用例子出发,逐步深入地了解它方便使用的背后原理。
文章主要内容:
Retrofit 请求实现流程基本认识
Retrofit 如何拿到请求信息
Retrofit 如何转换请求、响应信息
Retrofit 请求实现流程基本认识
Retrofit 的使用非常简单,基本分四步:
定义接口、方法、参数、返回值
构造 Retrofit
调用 retrofit.create() 获取实例
调用方法获取返回值,执行接下来的异步或者同步请求
1.首先定义接口、方法、参数、返回值
public interface IApiService { @GET("users/{user}/repos") Call<List<String>> listRepos(@Path("user") String user);
@GET("users/{user}/repos") Observable<List<String>> listReposObservable(@Path("user") String user);}
复制代码
一般来说方法的返回值是 retrofit2.Call,如果使用 RxJava 的话也可以是 Observable。
在 OkHttp 中,Call 的唯一实现就是 RealCall,它表示一个准备好被执行的请求;在 Retrofit 中也定义了一个 Call 接口,不过它俩的级别不一样,相较于 OkHttp.Call ,Retrofit.Call 增加了更多信息,这个我们后面介绍。
2.构造 Retrofit
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com") .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build();
复制代码
构造 Retrofit 的参数不多,就这么几个:
public static final class Builder { private final Platform platform; private @Nullable okhttp3.Call.Factory callFactory; //默认是 OkHttpClient private HttpUrl baseUrl; private final List<Converter.Factory> converterFactories = new ArrayList<>(); //转换器 private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(); //适配器,将 Call 转换成指定的类型 private @Nullable Executor callbackExecutor; private boolean validateEagerly; //...}
复制代码
其中 Converter 和 CallAdapter 是我们后面要关注的重点, ``Retrofit` 之所以灵活好用,离不开这两位大将。
3.调用 retrofit.create() 获取实例
retrofit.create(IApiService.class)
复制代码
这里用到了动态代理 Proxy.newProxyInstance() ,生成实例并且代理所有方法,当我们调用某个方法时,会调用这个代理的invoke() 方法,这也是 Retrofit 的重点,后面详细分析。
//Retrofit.create()public <T> T create(final Class<T> service) { Utils.validateServiceInterface(service); if (validateEagerly) { eagerlyValidateMethods(service); } return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service }, new InvocationHandler() { private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable { //... } });}
复制代码
4.调用方法获取返回值,执行异步或者同步请求
retrofit.create(IApiService.class) .listRepos("shixinzhang") //这里返回了 retrofit2.Call .enqueue(new Callback<List<String>>() { @Override public void onResponse(Call<List<String>> call, Response<List<String>> response) { List<String> body = response.body();
}
@Override public void onFailure(Call<List<String>> call, Throwable t) {
} });
复制代码
调用方法后之所以可以调用 enqueue() 方法,是因为我们在定义方法时返回值是 retrofit2.Call。
retrofit2.Call 的实现类是 OkHttpCall,它的成员属性有一个 okhttp3.Call,发起请求就是通过 okhttp3.Call 来的:
final class OkHttpCall<T> implements Call<T> { private final ServiceMethod<T, ?> serviceMethod; private final @Nullable Object[] args;
private volatile boolean canceled; private @Nullable okhttp3.Call rawCall; private @Nullable Throwable creationFailure; private boolean executed; //...}
复制代码
Retrofit 发起异步请求的实现:
//OkHttpCall.enqueue()@Override public void enqueue(final Callback<T> callback) { checkNotNull(callback, "callback == null");
okhttp3.Call call; //... call.enqueue(new okhttp3.Callback() { @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) { Response<T> response; try { response = parseResponse(rawResponse); } catch (Throwable e) { callFailure(e); return; }
try { callback.onResponse(OkHttpCall.this, response); } catch (Throwable t) { t.printStackTrace(); } }
@Override public void onFailure(okhttp3.Call call, IOException e) { callFailure(e); } //... });}
复制代码
拿到响应后调用了 parseResponse() 方法,这个方法把 okhttp3.Response 转成了 Retrofit.Response:
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException { ResponseBody rawBody = rawResponse.body(); //... int code = rawResponse.code(); if (code < 200 || code >= 300) { try { ResponseBody bufferedBody = Utils.buffer(rawBody); return Response.error(bufferedBody, rawResponse); } finally { rawBody.close(); } }
if (code == 204 || code == 205) { rawBody.close(); return Response.success(null, rawResponse); }
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody); try { T body = serviceMethod.toResponse(catchingBody); //从响应里解析、转成指定的类型 return Response.success(body, rawResponse); } catch (RuntimeException e) { throw e; }}
复制代码
可以看到,这个 parseResponse() 方法就是做了我们经常做的根据响应码判断,回调 success 或者 error 回调。
在方法的最后调用了 serviceMethod.toResponse() 将 okhttp3.Response 转换成指定的类型,具体的细节我们后面介绍。
OK,至此我们对 Retrofit 的发起请求到拿到响应有了基本的认识,用一张图概括一下:
接下来对一些核心细节进行深入学习。
上篇文章的的流程图中,我们有这些疑问:
接口的实现代理做了哪些额外操作?
接口中的信息是如何转换成请求信息?
拿到响应后是如何转换成指定的类型?
接下来我们一起来解决这些问题。
Retrofit 核心机制实现分析
接口的代理做了哪些操作
我们知道接口的动态代理实现是在 Retrofit.create() 方法中:
public <T> T create(final Class<T> service) { Utils.validateServiceInterface(service); //验证是不是接口,有没有继承别的接口 if (validateEagerly) { eagerlyValidateMethods(service); //预加载,默认 validateEagerly 是 false
} return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service }, new InvocationHandler() { private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable { //如果是 Object 的方法就直接调用 if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } //... ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method); OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.adapt(okHttpCall); } });}
复制代码
可以看到,这个 create() 方法首先验证了传入的 Class 是不是接口,然后为接口创建了代理实例。
以后调用这个实例的方法,都将经过这个匿名内部类 InvocationHandler 的 invoke() 方法。
我们知道任何类都会默认继承 Object 类,因此在 invoke() 方法中,遇到 Object 类的方法直接进行调用,不做任何处理。
然后就到了关键部分了:
//InvocationHandler.invoke() @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable { //... ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method); OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.adapt(okHttpCall); }
复制代码
在这部分做了三件事:
调用 loadServiceMethod() ,参数是当前调用的方法,返回一个 ServiceMethod 实例
创建了一个 OkHttpCall 实例,参数是 serviceMethod 和当前调用方法传递的参数
调用了 serviceMethod.adapt(okHttpCall) 返回被代理方法的返回值
先来看看这个 ServiceMethod 是干什么的。
正如其名,一个 ServiceMethod 对象对应于一个接口的方法,它的职责是:把对接口方法的调用转为一次 HTTP 调用(敲黑板,这是重点)。
它的成员属性有很多:
private final okhttp3.Call.Factory callFactory;private final CallAdapter<R, T> callAdapter;
private final HttpUrl baseUrl;private final Converter<ResponseBody, R> responseConverter;private final String httpMethod;private final String relativeUrl;private final Headers headers;private final MediaType contentType;private final boolean hasBody;private final boolean isFormEncoded;private final boolean isMultipart;private final ParameterHandler<?>[] parameterHandlers;
复制代码
除了关于请求信息的,其中最重要的就是两个: CallAdapter 和 Converter<F, T>。
CallAdapter 的作用是将我们在接口的方法中声明的返回值类型转成 retrofit2.Call,如果我们直接声明方法的返回值就是 retrofit2.Call, CallAdapter 就不需要做什么转换了,后面再详细介绍
Converter<F, T> 的作用是将用户的请求/响应类型 和 HTTP 的请求/响应类型进行转换,一般有两个,作用其实类似 OkHttp 的 BridgeInterceptor
回到 Retrofit.create() 中创建的代理的 invoke() 方法,先是调用了 loadServiceMethod() 方法返回一个 ServiceMethod,我们看看这个方法做了什么:
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
ServiceMethod<?, ?> loadServiceMethod(Method method) { ServiceMethod<?, ?> result = serviceMethodCache.get(method); if (result != null) return result;
synchronized (serviceMethodCache) { result = serviceMethodCache.get(method); if (result == null) { //缓存里没有就新建一个 result = new ServiceMethod.Builder<>(this, method).build(); serviceMethodCache.put(method, result); } } return result;}
复制代码
可以看到,这个方法先去一个 Map 里根据 Method 方法对象去查询有没有之前保存的 ServiceMethod,有就直接返回,没有就调用 ServiceMethod.Builder<>(this, method).build(); 新建一个然后保存。
去瞅瞅这个 Builder:
//ServiceMethod.Builderstatic final class Builder<T, R> { final Retrofit retrofit; //... Converter<ResponseBody, T> responseConverter; CallAdapter<T, R> callAdapter;
Builder(Retrofit retrofit, Method method) { this.retrofit = retrofit; this.method = method; this.methodAnnotations = method.getAnnotations(); this.parameterTypes = method.getGenericParameterTypes(); this.parameterAnnotationsArray = method.getParameterAnnotations(); }
public ServiceMethod build() { callAdapter = createCallAdapter(); //拿到可以处理当前接口方法的 ``CallAdapter`` responseType = callAdapter.responseType(); //... responseConverter = createResponseConverter(); //拿到可以处理当前接口方法的 ``responseConverter`` for (Annotation annotation : methodAnnotations) { parseMethodAnnotation(annotation); } //... return new ServiceMethod<>(this); } //...}
复制代码
ServiceMethod.Builder 的 build() 方法中主要做了 3 件事:
实例化用于处理当前接口方法的 callAdapter 和 responseConverter
解析方法上的注解信息
来分别看看如何实现的。
前面提到:
因此不同的方法如果返回值不同, ServiceMethod 中的CallAdapter 是不同的。
我们来看看 ServiceMethod 是怎么找到能处理当前方法的 CallAdapter :
private CallAdapter<T, R> createCallAdapter() { Type returnType = method.getGenericReturnType(); if (Utils.hasUnresolvableType(returnType)) { //首先判断返回值类型 throw methodError(//...); } if (returnType == void.class) { throw methodError("//..."); } Annotation[] annotations = method.getAnnotations(); try { //调用 retrofit 的方法 return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations); } catch (RuntimeException e) { //... }}
复制代码
如果你记不住 CallAdapter 是干嘛的,看到上面这个方法的前两个判断或许就能记住了,它是要处理返回值的,所以在创建前需要检查方法的返回值是否合理。
最后调用了 retrofit.callAdapter(returnType, annotations);:
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) { return nextCallAdapter(null, returnType, annotations);}
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) { checkNotNull(returnType, "returnType == null"); checkNotNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1; //遍历 Retrofit 创建时添加的 callAdapterFactory for (int i = start, count = callAdapterFactories.size(); i < count; i++) { CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this); if (adapter != null) { return adapter; } }
//... throw new IllegalArgumentException(builder.toString());}
复制代码
可以看到,最后找适用于当前方法的 CallAdapter 是通过遍历 Retrofit 创建时添加的 CallAdapter.Factory,然后调用每一个 factory 的 get() 方法,如果不为空表示能处理,就返回这个 CallAdapter。
Retrofit 中我们主要用到两个 CallAdapterFactory:
DefaultCallAdapterFactory 处理 Retrofit 默认返回值 Call<T> 的
RxJavaCallAdapterFactory 处理返回值为 Observable<T> 的
我们来简单看看 DefaultCallAdapterFactory.get() 方法:
final class DefaultCallAdapterFactory extends CallAdapter.Factory { //... @Override public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != Call.class) { //用于处理返回值是 Call return null; }
final Type responseType = Utils.getCallResponseType(returnType); return new CallAdapter<Object, Call<?>>() { //创建一个 CallAdapter,直接返回 Call @Override public Type responseType() { return responseType; }
@Override public Call<Object> adapt(Call<Object> call) { return call; } }; }}
复制代码
可以看到,默认的这个 DefaultCallAdapterFactory只能处理返回值是 Call,它返回的 CallAdapter 没有做额外工作,直接返回了这个返回值。
** ServiceMethod 寻找能处理当前方法的 Converter 的逻辑也是类似,去 Retrofit 的 converterFactory 列表里遍历寻找: **
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) { return nextResponseBodyConverter(null, type, annotations);}public <T> Converter<ResponseBody, T> nextResponseBodyConverter( @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) { //... int start = converterFactories.indexOf(skipPast) + 1; for (int i = start, count = converterFactories.size(); i < count; i++) { Converter<ResponseBody, ?> converter = converterFactories.get(i).responseBodyConverter(type, annotations, this); if (converter != null) { return (Converter<ResponseBody, T>) converter; } } //... throw new IllegalArgumentException(builder.toString());}
复制代码
小结一下:创建一个 ServiceMethod 是要给它找能处理当前返回值的 CallAdapter,它是通过去 Retrofit 的CallAdapter.Factory 列表(final List<CallAdapter.Factory> callAdapterFactories; )里挨个调用 get() 方法来寻找的,找 responseConverter 响应转换器也是一样的。
OK,ServiceMethod 的前两步我们都了解了,最后看一下如何解析方法上的注解信息。
//ServiceMethod.Builder.build()public ServiceMethod build() { //... for (Annotation annotation : methodAnnotations) { parseMethodAnnotation(annotation); }
//... int parameterCount = parameterAnnotationsArray.length; parameterHandlers = new ParameterHandler<?>[parameterCount]; for (int p = 0; p < parameterCount; p++) { Type parameterType = parameterTypes[p]; //... Annotation[] parameterAnnotations = parameterAnnotationsArray[p]; parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations); }
复制代码
可以看到解析方法上的注解信息主要分两步:
遍历方法上的所有注解 methodAnnotations 解析请求方法和地址
遍历参数中的所有注解 parameterAnnotationsArray 解析参数,比如相对路径、查询值,解析结果保存到 ParameterHandler 中
具体代码比较简单,这里就不再赘述了。
了解了 ServiceMethod 的创建后,代理方法的第二步是创建了一个 OkHttpCall,前面介绍请求流程时已经介绍过, OkHttpCall 就是对 okhttp3.Call 的封装,它的同步异步请求都是通过调用 okhttp3.Call 的方法实现的。
调用 okhttp3.Call 需要传递 okhttp.Request 请求信息,这里的请求信息就是通过持有前面创建的 ServiceMethod 来实现的。
在调用 OkHttpCall 的同步、异步请求时,会先调用 OkHttpCall.createRawCall() 方法创建一个 okhttp3.Call :
private okhttp3.Call createRawCall() throws IOException { okhttp3.Call call = serviceMethod.toCall(args); if (call == null) { throw new NullPointerException("Call.Factory returned null."); } return call;}
复制代码
可以看到是调用的 ServiceMethod 的 toCall() 方法创建的,这个 ServiceMethod 太关键了,一定要记住它。
//ServiceMethod.toCall()okhttp3.Call toCall(@Nullable Object... args) throws IOException { RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers, contentType, hasBody, isFormEncoded, isMultipart); ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers; int argumentCount = args != null ? args.length : 0; //... for (int p = 0; p < argumentCount; p++) { handlers[p].apply(requestBuilder, args[p]); }
return callFactory.newCall(requestBuilder.build());}
复制代码
可以看到,这个方法就是把前面解析注解拿到的数据都组装起来,创建一个 Request 传递给 OkHttpClient。
前两步清楚了,最后看第三步 serviceMethod.adapt(okHttpCall):
//ServiceMethod.adapt()T adapt(Call<R> call) { return callAdapter.adapt(call);}
复制代码
我们知道当返回值类型是 Call 时 CallAdapter 的不做任何操作,也就是做,调用这个 ServiceMethod.adapt() 方法的作用就是返回上一步创建的 OkHttpCall。
当我们使用 RxJava 时返回值是 Observable,这时的 CallAdapter 的作用就是将 Observable 转换成 OkHttpCall。
OK,至此我们对代理做了什么算是彻底了解了,总结一下:
解析注解,创建能处理当前方法的 CallAdapter 和 Converter
创建封装底层 okhttp3.Call 的 OkHttpCall,这个类在执行网络请求时,会根据之前创建的 ServiceMethod 来组装请求信息
将方法的返回值转换成要做请求的 OkHttpCall,当返回值是 Call 时就不做任何处理
如果有使用 retrofit2.http.Body 修饰的参数,这个对象会被某一个 Converter.Factory 实例转换成 OkHttp 请求体(okhttp3.RequestBody)
Converter<F, T>的作用是将用户的请求/响应类型 和 HTTP 的请求/响应类型进行转换,一般有两个,作用其实类似OkHttp的BridgeInterceptor``
Retrofit 如何拿到请求信息
我们使用 Retrofit 时只要定义接口和方法,然后使用注解表示请求方法、请求参数以及输入返回值即可。
那它进行网络请求时是如何拿到请求信息的呢?
上一节中介绍代理拦截方法时做的工作时,我们已经得到了答案:
Retrofit.create() 方法为接口创建动态代理
当调用接口的方法时,会调用拦截的 invoke() 方法
在这个方法里先是创建了 ServiceMethod(它可以解析方法上的注解和参数的注解,同时寻找能处理当前方法的 CallAdapter 和 Converter)
然后创建了封装底层请求的 OkHttpCall,这个类会在做请求时,根据 ServiceMethod 的信息创建一个 okhttp3.Request,从而创建一个 okhttp3.Call 做网络请求
Retrofit 如何转换请求、响应信息
经过前面的学习我们知道,Retrofit 中 Converter 就是负责转换 请求、响应信息 的。它一般有两种:
将使用 @Body 修饰的参数转换成请求体
将网络响应的响应体 ResponseBody 转换成用户指定的类型
先看如何实现将使用 @Body 修饰的参数转换成请求体。
我们使用 Retrofit 做 POST 请求时,可以使用 @Body 注解修饰一个实体,它表示要提交的请求体:
public interface IApiService {
@POST("users//repos/update") Call<List<Result>> updateRepos(@Body RepoInfo repoInfo);}
复制代码
我们知道 ServiceMethod 负责解析方法参数的注解,我们来看看它遇到 @Body 是如何解析的吧:
private ParameterHandler<?> parseParameterAnnotation( //... } else if (annotation instanceof Body) { //... Converter<?, RequestBody> converter; try { converter = retrofit.requestBodyConverter(type, annotations, methodAnnotations); } catch (RuntimeException e) { //... } gotBody = true; return new ParameterHandler.Body<>(converter); } //...}
复制代码
可以看到,在解析参数注解时,遇到注解是 Body 时,会调用 retrofit.requestBodyConverter() ,这个方法和前面寻找转换响应数据的 responseConverter 一样,都是遍历 Retrofit 中的转换器工厂列表。
最常使用的转换器工厂是 GsonConverterFactory,我们来看看它定义的请求体解析器是什么样的:
//GsonConverterFactory.requestBodyConverter()@Overridepublic Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); return new GsonRequestBodyConverter<>(gson, adapter);}//GsonRequestBodyConverter.convert()@Override public RequestBody convert(T value) throws IOException { Buffer buffer = new Buffer(); Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8); JsonWriter jsonWriter = gson.newJsonWriter(writer); adapter.write(jsonWriter, value); jsonWriter.close(); return RequestBody.create(MEDIA_TYPE, buffer.readByteString());}
复制代码
可以看到,使用 Gson 实现的请求体转换器比较简单,就是拿到 Type 后创建一个 TypeAdapter ,然后读取数据,将它转成 RequestBody。
接着看看拿到网络响应响应体 ResponseBody 后,如何转换成用户指定的类型。
在 OkHttpCall 的同步或者异步请求最后,都调用了 parseResponse() 方法,这个方法除了根据响应码做回调,最后还做了转换工作:
//OkHttpCall.parseResponseResponse<T> parseResponse(okhttp3.Response rawResponse) throws IOException { //... int code = rawResponse.code(); if (code < 200 || code >= 300) { try { ResponseBody bufferedBody = Utils.buffer(rawBody); return Response.error(bufferedBody, rawResponse); } finally { rawBody.close(); } } //... ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody); try { T body = serviceMethod.toResponse(catchingBody); return Response.success(body, rawResponse); } catch (RuntimeException e) { //... throw e; }}
复制代码
又见 ServiceMethod,这哥们从请求开始到请求结束,一直负责重要的功能,大家一定要记住它!!!
ServiceMethod.toResponse() 方法也很简单,就是调用转换器:
//ServiceMethod.toResponseR toResponse(ResponseBody body) throws IOException { return responseConverter.convert(body);}
复制代码
还是看看常用的 Gson 响应转换器:
//GsonConverterFactory.responseBodyConverter()public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); return new GsonResponseBodyConverter<>(gson, adapter);}//GsonResponseBodyConverter.convert()@Override public T convert(ResponseBody value) throws IOException { JsonReader jsonReader = gson.newJsonReader(value.charStream()); try { return adapter.read(jsonReader); } finally { value.close(); }}
复制代码
很简单就两步:
根据方法中的返回值数据类型 Type 创建 TypeAdapter
调用 JsonReader 进行读取,将 ResponseBody 转换成指定的类型
具体 Gson 原理这里就暂不赘述了。
OK 小结一下 Retrofit 如何转换请求、响应信息: 两个转换器搞定!
Retrofit 请求实现流程总结
一张图总结 Retrofit 网络请求实现原理:
Retrofit 中最核心的就这几点:
动态代理,代理类做了什么工作要清楚
老熟人 ServiceMethod 都做了什么重要的工作
CallAdapter 负责将方法里的返回值转换成上层的 OkHttpCall
两个 Converter 分别实现自己传的对象到请求体、响应体到自己定义的对象的转换
看着流程图能把这四点说明白,你就掌握了!
评论