Retrofit2.5怎么做到网络请求的处理的()

Retrofit对请求方法的解析 Retrofit对我们在接口类中定义的方法是如何转换成了请求,又如何处理响应。这一切都在它的loadServiceMethod方法中

代码基于Retrofit2.5.0
ServiceMethod loadServiceMethod(Method method) { ServiceMethod result = serviceMethodCache.get(method); if (result != null) return result; synchronized (serviceMethodCache) { result = serviceMethodCache.get(method); if (result == null) { result = ServiceMethod.parseAnnotations(this, method); serviceMethodCache.put(method, result); } } return result; }

【Retrofit2.5怎么做到网络请求的处理的()】主要是调用ServiceMethod.parseAnnotations
static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) { RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method); //这里就是对请求的解析,也就是我们定义的接口方法Type returnType = method.getGenericReturnType(); //获取返回的类型 //省略无关代码return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); }

RequestFactory.parseAnnotations这个方法就是对我们定义的接口方法的解析,在里面解析注解和使用反射得到了关于请求的所有信息。
响应的处理 在完成了对请求的处理后构建了RequestFactory类,这个类里面包含了请求的所有信息:
final class RequestFactory { static RequestFactory parseAnnotations(Retrofit retrofit, Method method) { return new Builder(retrofit, method).build(); }private final Method method; private final HttpUrl baseUrl; final String httpMethod; private final @Nullable String relativeUrl; private final @Nullable Headers headers; private final @Nullable MediaType contentType; private final boolean hasBody; private final boolean isFormEncoded; private final boolean isMultipart; private final ParameterHandler[] parameterHandlers;

接下来继续来看ServiceMethod的parseAnnotations剩下的语句
ServiceMethod.parseAnnotations
static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) { //省略无关代码return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); //对响应的处理 }

HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)
static HttpServiceMethod parseAnnotations( Retrofit retrofit, Method method, RequestFactory requestFactory) { CallAdapter callAdapter = createCallAdapter(retrofit, method); //创建请求适配器 Type responseType = callAdapter.responseType(); //省略无关代码 Converter responseConverter = createResponseConverter(retrofit, method, responseType); //创建响应数据转换器(Gson)okhttp3.Call.Factory callFactory = retrofit.callFactory; //Okhttp请求客户端 return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter); }

创建请求适配器CallAdapter
首先进入第一行
HttpServiceMethod.createCallAdapter
private static CallAdapter createCallAdapter( Retrofit retrofit, Method method) { Type returnType = method.getGenericReturnType(); //获取返回的类型 Annotation[] annotations = method.getAnnotations(); //获取注解 try { //noinspection unchecked return (CallAdapter) retrofit.callAdapter(returnType, annotations); } catch (RuntimeException e) { // Wide exception range because factories are user code. throw methodError(method, e, "Unable to create call adapter for %s", returnType); } }

在获取了方法的返回类型和注解之后,调用
retrofit.callAdapter
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; for (int i = start, count = callAdapterFactories.size(); i < count; i++) { CallAdapter adapter = callAdapterFactories.get(i).get(returnType, annotations, this); if (adapter != null) { return adapter; } } }

这里面是一个循环获取请求适配器工厂数组callAdapterFactories,在retrofit创建的时候,我们可以知道往这个数组里面加的是Android平台默认的ExecutorCallAdapterFactory
public Retrofit build() { List callAdapterFactories = new ArrayList<>(this.callAdapterFactories); callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor)); } static class Android extends Platform { @Override List defaultCallAdapterFactories( @Nullable Executor callbackExecutor) { if (callbackExecutor == null) throw new AssertionError(); //这里可以看到返回的类 ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor); return Build.VERSION.SDK_INT >= 24 ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory) : singletonList(executorFactory); } }

在刚才的循环里,调用了它的get方法,实际就是调用
ExecutorCallAdapterFactory.get
@Override public @Nullable CallAdapter get( Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != Call.class) { return null; } final Type responseType = Utils.getCallResponseType(returnType); //根据返回类型获取泛型里面的想要获取的响应类型 return new CallAdapter>() { @Override public Type responseType() { return responseType; }@Override public Call adapt(Call call) { return new ExecutorCallbackCall<>(callbackExecutor, call); } }; }
我们定义的返回类型一般是泛型的形式,如Call或者Observable,所以Utils.getCallResponseType就是取出泛型里面的类型。最后将得到的类型传入新建的CallAdapter
return new CallAdapter>() { @Override public Type responseType() { return responseType; }@Override public Call adapt(Call call) { return new ExecutorCallbackCall<>(callbackExecutor, call); } };
自此就完成了CallAdapter的创建,这里记住它的adapt方法,里面是返回的ExecutorCallbackCall,这个后面会调用,再来继续看。
HttpServiceMethod的parseAnnotations第一行代码到此就完了,继续往下执行:
创建响应数据转换器(如Gson)和请求客户端
HttpServiceMethod.parseAnnotations
static HttpServiceMethod parseAnnotations( Retrofit retrofit, Method method, RequestFactory requestFactory) { CallAdapter callAdapter = createCallAdapter(retrofit, method); Type responseType = callAdapter.responseType(); //获取具体的响应类型 //省略无关代码 Converter responseConverter = createResponseConverter(retrofit, method, responseType); okhttp3.Call.Factory callFactory = retrofit.callFactory; return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter); }

注意这里传给responseConverter的responseType是我们刚才获取Call泛型里面的具体类型,也就是我们想要拿到的实体类类型。
这个过程跟刚才创建CallAdapter的过程很像,就连方法名都很像,所以来看看createResponseConverter方法:
HttpServiceMethod.createResponseConverter
private static Converter createResponseConverter( Retrofit retrofit, Method method, Type responseType) { Annotation[] annotations = method.getAnnotations(); try { return retrofit.responseBodyConverter(responseType, annotations); } catch (RuntimeException e) { // Wide exception range because factories are user code. throw methodError(method, e, "Unable to create converter for %s", responseType); } }

通过method的getAnnotations拿到注解列表,然后跟返回类型传入responseBodyConverter方法:
retrofit.responseBodyConverter
public Converter responseBodyConverter(Type type, Annotation[] annotations) { return nextResponseBodyConverter(null, type, annotations); }

public Converter nextResponseBodyConverter( @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) { checkNotNull(type, "type == null"); checkNotNull(annotations, "annotations == null"); int start = converterFactories.indexOf(skipPast) + 1; for (int i = start, count = converterFactories.size(); i < count; i++) { Converter converter = converterFactories.get(i).responseBodyConverter(type, annotations, this); if (converter != null) { //noinspection unchecked return (Converter) converter; } }

这个过程简直跟刚才创建CallAdapter的过程一模一样,也是循环从converterFactories取出Converter,根据之前Retrofit的创建时我们传入的是GsonConverterFactory,所以是调用的它的responseBodyConverter方法:
GsonConverterFactory.responseBodyConverter
public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { TypeAdapter adapter = gson.getAdapter(TypeToken.get(type)); return new GsonResponseBodyConverter<>(gson, adapter); }

这里的代码就很面熟了,通过TypeToken获取类型,之后返回一个Gson解析器,它的convert就是调用Gson进行泛型的解析。
GsonResponseBodyConverter
final class GsonResponseBodyConverter implements Converter { private final Gson gson; private final TypeAdapter adapter; GsonResponseBodyConverter(Gson gson, TypeAdapter adapter) { this.gson = gson; this.adapter = adapter; }@Override public T convert(ResponseBody value) throws IOException { JsonReader jsonReader = gson.newJsonReader(value.charStream()); try { T result = adapter.read(jsonReader); if (jsonReader.peek() != JsonToken.END_DOCUMENT) { throw new JsonIOException("JSON document was not fully consumed."); } return result; } finally { value.close(); } } }

到这里就完成了响应字符串的解析器的创建,接下来会执行
okhttp3.Call.Factory callFactory = retrofit.callFactory; return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);

创建okhttp请求的客户端,这里命名为callFactory,在Retrofit创建的时候我们传入的okhttpClient就是赋值给了callFactory,最后将创建好的对象传入HttpServiceMethod返回。
到此为止就执行完了HttpServiceMethod的parseAnnotations方法,在这个方法里面,创建了几个重要的东西
  • 对请求和响应做具体处理的CallAdapter类,具体为ExecutorCallAdapterFactory,这里要注意它的adapt方法返回ExecutorCallbackCall类
  • 响应数据解析工厂Converter,具体为GsonResponseBodyConverter
  • okhttp请求客户端
发送请求 终于到了这一步了,在做好了所有的准备工作之后,最终Retrofit怎么来发送请求呢,首先一步步回到最开始的地方:
在HttpServiceMethod.parseAnnotations方法是在ServiceMethod的parseAnnotations调用的
ServiceMethod.parseAnnotations
abstract class ServiceMethod { static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) { RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method); Type returnType = method.getGenericReturnType(); if (Utils.hasUnresolvableType(returnType)) { throw methodError(method, "Method return type must not include a type variable or wildcard: %s", returnType); } if (returnType == void.class) { throw methodError(method, "Service methods cannot return void."); }//在这里调用并返回 return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); }abstract T invoke(Object[] args); }

然后ServiceMethod.parseAnnotations方法是在Retrofit的loadServiceMethod调用的
然后loadServiceMethod是在Retrofit的create方法里面创建动态代理的invoke调用的
Retrofit.create
public T create(final Class service) { //省略无关代码 return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[] { service }, new InvocationHandler() { //省略无关代码@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable { //省略无关代码 return loadServiceMethod(method).invoke(args != null ? args : emptyArgs); } }); }

可以看到,在loadServiceMethod之后调用了invoke方法,也就是ServiceMethod的invoke方法,点进去之后发现它是个ServiceMethod是个抽象类,它的invoke需要实现类来重写:
abstract class ServiceMethod { abstract T invoke(Object[] args); }

ServiceMethod类只有一个实现类,也就是我们刚才看到过的HttpServiceMethod,所以实际上调用的是它的invoke方法:
HttpServiceMethod.invoke
@Override ReturnT invoke(Object[] args) { return callAdapter.adapt( new OkHttpCall<>(requestFactory, args, callFactory, responseConverter)); }

在这里只有一行代码,实际上是调用callAdapter.adapt,那这个callAdapter是什么呢?刚才我们已经知道它是ExecutorCallAdapterFactory创建的,然后在创建的callAdapter的adapt方法返回ExecutorCallbackCall类,所以来看看这个类:
ExecutorCallbackCall是ExecutorCallAdapterFactory的静态内部类
ExecutorCallbackCall
static final class ExecutorCallbackCall implements Call { final Executor callbackExecutor; final Call delegate; ExecutorCallbackCall(Executor callbackExecutor, Call delegate) { this.callbackExecutor = callbackExecutor; this.delegate = delegate; }@Override public void enqueue(final Callback callback) { checkNotNull(callback, "callback == null"); delegate.enqueue(new Callback() { @Override public void onResponse(Call call, final Response response) { callbackExecutor.execute(new Runnable() { @Override public void run() { if (delegate.isCanceled()) { // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation. callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled")); } else { callback.onResponse(ExecutorCallbackCall.this, response); } } }); }@Override public void onFailure(Call call, final Throwable t) { callbackExecutor.execute(new Runnable() { @Override public void run() { callback.onFailure(ExecutorCallbackCall.this, t); } }); } }); }@Override public boolean isExecuted() { return delegate.isExecuted(); }@Override public Response execute() throws IOException { return delegate.execute(); }@Override public void cancel() { delegate.cancel(); }@Override public boolean isCanceled() { return delegate.isCanceled(); }@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone. @Override public Call clone() { return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone()); }@Override public Request request() { return delegate.request(); } }

在这个类里面,我们就看到了很多很熟悉的方法,enqueue方法发送请求,实际的请求和处理就是在这里面,但是还有疑惑就是具体的处理我们还是没看到,callbackExecutor和delegate这两个熟悉才是关键所在:
callbackExecutor 这个是在ExecutorCallAdapterFactory的构造方法中传入的,它的构造方法又是在Platform的defaultCallAdapterFactories方法中调用的,看到Platform,自然可以想到它的Android平台类,所以这个callbackExecutor实际上是MainThreadExecutor
@Override public Executor defaultCallbackExecutor() { return new MainThreadExecutor(); }static class MainThreadExecutor implements Executor { private final Handler handler = new Handler(Looper.getMainLooper()); @Override public void execute(Runnable r) { handler.post(r); } }

其实代码很简单,使用了我们最常用的Handler,让代码在主线程中执行,也就是我们通常做的在子线程请求网络,主线程中更新UI。
delegate delegate实际是在HttpServiceMethod的invoke方法里传入:
@Override ReturnT invoke(Object[] args) { return callAdapter.adapt( new OkHttpCall<>(requestFactory, args, callFactory, responseConverter)); }

实际上是OkHttpCall这个类,这个类里面就是发送请求和处理响应的具体处理,代码很多,我们只看看构造方法和enqueue
OkHttpCall(RequestFactory requestFactory, Object[] args, okhttp3.Call.Factory callFactory, Converter responseConverter) { this.requestFactory = requestFactory; //请求工厂,里面包含了请求的所有信息 this.args = args; //参数 this.callFactory = callFactory; //请求客户端,okhttp this.responseConverter = responseConverter; //响应的json解析器(Gson) }

OkHttpCall.enqueue
@Override public void enqueue(final Callback callback) { checkNotNull(callback, "callback == null"); okhttp3.Call call; Throwable failure; synchronized (this) { if (executed) throw new IllegalStateException("Already executed."); executed = true; call = rawCall; failure = creationFailure; if (call == null && failure == null) { try { call = rawCall = createRawCall(); } catch (Throwable t) { throwIfFatal(t); failure = creationFailure = t; } } }if (failure != null) { callback.onFailure(this, failure); return; }if (canceled) { call.cancel(); }call.enqueue(new okhttp3.Callback() { @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) { Response response; try { response = parseResponse(rawResponse); } catch (Throwable e) { throwIfFatal(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); }private void callFailure(Throwable e) { try { callback.onFailure(OkHttpCall.this, e); } catch (Throwable t) { t.printStackTrace(); } } }); }

代码其实很简单,就是使用okhttp请求,然后在响应方法onResponse做相应的解析和处理,最后完成网络请求。
总结 Retrofit对响应的解析大概可分为
  1. 创建处理适配器CallAdapter,具体实现类为ExecutorCallbackCall,在这里面进行发送请求和处理响应等相关的操作,最终是调用okhttp进行网络请求
  2. 创建响应数据转换器Converter,具体实现类为GsonResponseBodyConverter,用于对返回json数据的解析,这个是我们自己传入的Gson解析工厂,Retrofit也支持其他的第三方解析库
  3. 发送请求,具体的操作类是OkHttpCall来发送请求和处理响应,MainThreadExecutor来做回调的处理,在主线程中处理已经转化好的实体类。
Retrofit2.5怎么做到网络请求的处理的()
文章图片
聊技术 聊电影 聊人生 什么都聊的公众号

    推荐阅读