Retrofit2源码阅读
来源:互联网 发布:未转变者服务器端口 编辑:程序博客网 时间:2024/06/06 00:42
Retrofit2源码阅读(版本:com.squareup.retrofit2:retrofit:2.3.0)
这个图来自trello,貌似一个叫Stay的大佬做的?感谢大佬。
用一个网络请求的流程来分析阅读,以simples包下的SimpleService为例:
// Create a very simple REST adapter which points the GitHub API. // https://api.github.com/repos/square/retrofit/contributors Retrofit retrofit = new Retrofit.Builder() .baseUrl(API_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); // Create an instance of our GitHub API interface. GitHub github = retrofit.create(GitHub.class); // Create a call instance for looking up Retrofit contributors. Call<List<Contributor>> call = github.contributors("square", "retrofit"); // Fetch and print a list of the contributors to the library. List<Contributor> contributors = call.execute().body(); .....
addConverterFactory方法加入一个Converter工厂,如retrofit2.converter.gson.GsonConverterFactory.
public Builder addConverterFactory(Converter.Factory factory) { converterFactories.add(checkNotNull(factory, "factory == null")); return this; }
retrofit2.Retrofit.Builder#build:
public Retrofit build() { if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory == null) { callFactory = new OkHttpClient(); } Executor callbackExecutor = this.callbackExecutor; if (callbackExecutor == null) { callbackExecutor = platform.defaultCallbackExecutor(); } // Make a defensive copy of the adapters and add the default Call adapter. List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories); adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); // Make a defensive copy of the converters. List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories); return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly); }
调用retrofit2.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 { // If the method is a method from Object then defer to normal invocation. if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } if (platform.isDefaultMethod(method)) { return platform.invokeDefaultMethod(method, service, proxy, args); } ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>) loadServiceMethod(method); OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall); } }); }
retrofit2.Retrofit#loadServiceMethod会去serviceMethodCache根据method查找ServiceMethod,如果没有查到,就根据Retrofit对象和method创建一个ServiceMethod(把接口方法的调用适配为一个Http call)。以Method为key,ServiceMethod为value的放入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; }
retrofit2.ServiceMethod#toRequest:
/** Builds an HTTP request from method arguments. */ Request toRequest(@Nullable Object... args) throws IOException { RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers, contentType, hasBody, isFormEncoded, isMultipart); @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types. ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers; int argumentCount = args != null ? args.length : 0; if (argumentCount != handlers.length) { throw new IllegalArgumentException("Argument count (" + argumentCount + ") doesn't match expected count (" + handlers.length + ")"); } for (int p = 0; p < argumentCount; p++) { handlers[p].apply(requestBuilder, args[p]); } return requestBuilder.build(); }
retrofit2.OkHttpCall#createRawCall:根据url的参数生成Okhttp3的request ,和call;
private okhttp3.Call createRawCall() throws IOException { Request request = serviceMethod.toRequest(args); okhttp3.Call call = serviceMethod.callFactory.newCall(request); if (call == null) { throw new NullPointerException("Call.Factory returned null."); } return call; }
okhttp3.RealCall#execute:
@Override public Response execute() throws IOException { synchronized (this) { if (executed) throw new IllegalStateException("Already Executed"); executed = true; } captureCallStackTrace(); try { client.dispatcher().executed(this); Response result = getResponseWithInterceptorChain(); if (result == null) throw new IOException("Canceled"); return result; } finally { client.dispatcher().finished(this); } }
retrofit2.OkHttpCall#parseResponse,根据T转化为ArrayList。
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException { ResponseBody rawBody = rawResponse.body(); // Remove the body's source (the only stateful object) so we can pass the response along. rawResponse = rawResponse.newBuilder() .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength())) .build(); int code = rawResponse.code(); if (code < 200 || code >= 300) { try { // Buffer the entire body to avoid future I/O. 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) { // If the underlying source threw an exception, propagate that rather than indicating it was // a runtime exception. catchingBody.throwIfCaught(); throw e; } }
retrofit2.ServiceMethod#toResponse:
/** Builds a method return value from an HTTP response body. */ R toResponse(ResponseBody body) throws IOException { return responseConverter.convert(body); }
这里因为之前传入的是retrofit2.converter.gson.GsonConverterFactory,由retrofit2.Converter.Factory#responseBodyConverter获得retrofit2.converter.gson.GsonResponseBodyConverter,把ResponseBody 转化为ArrayList返回。ok,完整的一个请求流程就是这些。
- Retrofit2源码的阅读
- Retrofit2源码阅读
- Retrofit2.0源码分析
- Retrofit2源码分析
- Retrofit2源码初探
- Retrofit2源码解读
- Retrofit2源码解析
- Retrofit2 源码解析
- Retrofit2.0源码解析
- Retrofit2 源码解读
- Retrofit2 源码分析
- Retrofit2 源码解析
- Retrofit2 源码解析
- Retrofit2 源码分析
- Retrofit2源码解读
- Retrofit2 源码解析
- Retrofit2 源码解析
- Retrofit2 源码解析
- iOS 获取APP名称 版本等
- 防止xss攻击
- cookies,sessionStorage 和 localStorage
- 解析微服务架构(一):什么是微服务
- 哈哈
- Retrofit2源码阅读
- elasticsearch 5.x 搭建学习过程
- linux系统下程序编译过程
- Linux常用命令
- tensorflow的MNIST
- log4j将指定的日志保存到指定的文件里
- 深入HBase架构解析(一)
- 对整数数组里所有的数字拼接起来,输出最小的一个
- radio和checkbox样式的修改