平时有在用 OkHttp 和 Retrofit 两个框架,一时兴起想读一下源码顺便写篇博客。写得很长…很枯燥…emmmm……权当是自己的学习笔记吧。如果在此之外还能帮到也想了解这两个框架的朋友,那是最好不过了,哈哈。
OkHttp
先来看一下 OkHttp 的最基础使用。
// Step 1
OkHttpClient okHttpClient = new OkHttpClient();
// Step 2
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();
// Step 3 同步请求
try {
okhttp3.Response response = okHttpClient.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
// Step 3 异步请求
okHttpClient.newCall(request).enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
}
});
OkHttp最基础的使用分为三步,第一步创建 OkHttpClient,第二步创建一个 Request,最后一步就是请求,请求又分为同步请求和异步请求,我们从这个流程出发,读一下这个流程实现的源码。
创建 OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient();
看一下它这个无参构造函数。
public OkHttpClient() {
this(new Builder());
}
可以发现无参构造函数内部调用的是有一个 Builder 类型参数的构造函数。先看一下传入的 Builder 参数。这边传入的 Builder 参数,是用 new Builder() 创建了一个对象,来看看这个 new Builder() 是创建了一个怎样的对象。
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
eventListenerFactory = EventListener.factory(EventListener.NONE);
proxySelector = ProxySelector.getDefault();
cookieJar = CookieJar.NO_COOKIES;
socketFactory = SocketFactory.getDefault();
hostnameVerifier = OkHostnameVerifier.INSTANCE;
certificatePinner = CertificatePinner.DEFAULT;
proxyAuthenticator = Authenticator.NONE;
authenticator = Authenticator.NONE;
connectionPool = new ConnectionPool();
dns = Dns.SYSTEM;
followSslRedirects = true;
followRedirects = true;
retryOnConnectionFailure = true;
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
pingInterval = 0;
}
从 Builder 的构造方法中可以看出,它主要的工作是初始化一些值,此无参的 Builder 构造方法初始化的值采用的是默认的值。由 Builder 这个名字就可以知道,它是 Builder 模式的,可以用 Builder 模式的方式链式地自定义初始化各个参数,这里不予展开。当我们的 Builder 对象创建好时,就可以把它作为参数传给 OkHttpClient(Builder builder) 构造方法,构造 OkHttpClient 对象。
OkHttpClient(Builder builder) {
this.dispatcher = builder.dispatcher;
this.proxy = builder.proxy;
this.protocols = builder.protocols;
this.connectionSpecs = builder.connectionSpecs;
this.interceptors = Util.immutableList(builder.interceptors);
this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
this.eventListenerFactory = builder.eventListenerFactory;
this.proxySelector = builder.proxySelector;
this.cookieJar = builder.cookieJar;
this.cache = builder.cache;
this.internalCache = builder.internalCache;
this.socketFactory = builder.socketFactory;
boolean isTLS = false;
for (ConnectionSpec spec : connectionSpecs) {
isTLS = isTLS || spec.isTls();
}
if (builder.sslSocketFactory != null || !isTLS) {
this.sslSocketFactory = builder.sslSocketFactory;
this.certificateChainCleaner = builder.certificateChainCleaner;
} else {
X509TrustManager trustManager = Util.platformTrustManager();
this.sslSocketFactory = newSslSocketFactory(trustManager);
this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);
}
if (sslSocketFactory != null) {
Platform.get().configureSslSocketFactory(sslSocketFactory);
}
this.hostnameVerifier = builder.hostnameVerifier;
this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(
certificateChainCleaner);
this.proxyAuthenticator = builder.proxyAuthenticator;
this.authenticator = builder.authenticator;
this.connectionPool = builder.connectionPool;
this.dns = builder.dns;
this.followSslRedirects = builder.followSslRedirects;
this.followRedirects = builder.followRedirects;
this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
this.connectTimeout = builder.connectTimeout;
this.readTimeout = builder.readTimeout;
this.writeTimeout = builder.writeTimeout;
this.pingInterval = builder.pingInterval;
if (interceptors.contains(null)) {
throw new IllegalStateException("Null interceptor: " + interceptors);
}
if (networkInterceptors.contains(null)) {
throw new IllegalStateException("Null network interceptor: " + networkInterceptors);
}
}
从这个构造函数中可以看出,它主要的工作就是把之前创建的 Builder 中的参数赋给 OkHttpClient 中的对象。到此,一个 OkHttpClient 对象就创建好了。
创建 Request
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();
Request 采用的也是 Builder 模式,Request.Builder 是 Request 的内部类。通过 Builder 里的各种方法,设置各个参数。
最后调用的 build() 方法,返回的是一个 Request 对象,将 Builder 对象本身作为参数传给 Request 构造函数。
public Request build() {
if (url == null) throw new IllegalStateException("url == null");
return new Request(this);
}
看一下 Request 构造方法。
Request(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers.build();
this.body = builder.body;
this.tags = Util.immutableMap(builder.tags);
}
很简单,就是将 Builder 对象中设置好的参数赋给 Requset 对象。
创建 OkHttpClient 和 Request 对象的两个步骤都不复杂,主要是一些参数的初始化与赋值,OkHttp 关键的就是下面的请求部分。
请求部分
先拿同步请求来讲。
try {
okhttp3.Response response = okHttpClient.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
请求先调用了 okHttpClient 的 newCall 方法,并将之前创建的 request 作为参数传入。看一下这个 newCall 方法做了什么操作。
/**
* Prepares the {@code request} to be executed at some point in the future.
*/
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
可以看到它并没有做什么操作,而是调用了 RealCall.newRealCall 方法,并将 okHttpClient (this), request 对象作为参数传入,false 表示与 Socket 不相关。我们继续看一下 RealCall.newRealCall方法。
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
// Safely publish the Call instance to the EventListener.
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.eventListener = client.eventListenerFactory().create(call);
return call;
}
newRealCall 方法中,先利用参数构造出了一个 RealCall 对象,然后调用我们之前创建的 okHttpClient 的 eventListenerFactory 来创建一个 eventListener,传入的参数是 RealCall 对象,将创建的 eventListener 赋给 RealCall 的 eventListener 。eventListener 的作用是监听应用程序HTTP调用的数量、大小和持续时间。
所以最终通过 okHttpClient.newCall(request) 得到的是一个 RealCall 对象。然后的步骤是调用 RealCall 对象的 execute 方法。来看一下 execute 方法。
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
eventListener.callFailed(this, e);
throw e;
} finally {
client.dispatcher().finished(this);
}
}
execute方法中,最关键的代码就是。
Response result = getResponseWithInterceptorChain();
这个方法的方法名很直接地告诉了我们,此方法通过拦截器链获取请求结果。看一下这个方法。
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
可以从方法中看出,主要是将用户定义的 Interceptor 和 官方定义的 Interceptor 放入一个 List 中,然后创建了一个 RealInterceptorChain 拦截器链,最后调用 RealInterceptorChain 的 proceed 方法来获取请求结果。看一下 proceed 方法中做了些什么。
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
calls++;
// If we already have a stream, confirm that the incoming request will use it.
if (this.httpCodec != null && !this.connection.supportsUrl(request.url())) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must retain the same host and port");
}
// If we already have a stream, confirm that this is the only call to chain.proceed().
if (this.httpCodec != null && calls > 1) {
throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
+ " must call proceed() exactly once");
}
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
writeTimeout);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
// Confirm that the next interceptor made its required call to chain.proceed().
if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) {
throw new IllegalStateException("network interceptor " + interceptor
+ " must call proceed() exactly once");
}
// Confirm that the intercepted response isn't null.
if (response == null) {
throw new NullPointerException("interceptor " + interceptor + " returned null");
}
if (response.body() == null) {
throw new IllegalStateException(
"interceptor " + interceptor + " returned a response with no body");
}
return response;
}
此方法中关键的代码是。
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
writeTimeout);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
该方法中 index 表示的是拦截器在拦截器链中的下标,可以看到代码中有一个 index + 1 的操作,就可以知道,请求会经过拦截器的处理,一步一步传给下一个拦截器,等到最后一个拦截器获取到最初步的 response 后,又会一层一层向上传,再通过一个个拦截器的处理,得到最终的 response,整个 OkHttp 同步请求就完成了。现在关键是要知道各个拦截器做了什么工作。
根据在拦截器中的顺序,有以下拦截器。自定义的Interceptor、RetryAndFollowUpInterceptor、BridgeInterceptor、CacheInterceptor、ConnectInterceptor、CallServerInterceptor。拦截器都要实现 Interceptor 接口。各个拦截器的功能简单介绍一下。
- 自定义的 Interceptor,功能当然是根据需求自定义的,不过要注意的是自定义的 Interceptor 必须实现 Interceptor 接口。
- RetryAndFollowUpInterceptor,功能是解决在请求时发生的错误并按照需求重定向。
- BridgeInterceptor,是从应用程序代码到网络代码的桥梁。首先,它从用户请求建立网络请求,然后继续呼叫网络。最后,根据网络响应建立用户响应。
- CacheInterceptor,缓存操作,数据有缓存就从缓存中获取,没有缓存就继续从网络上请求,将请求的结果写入缓存中。
- ConnectInterceptor,打开目标服务器的连接并进入下一个拦截器。
- CallServerInterceptor,链中的最后一个拦截器,它对服务器进行网络调用。
Interceptor 是 OkHttp 最关键最核心的部分。
再来看一下 OkHttp 异步请求部分的源码。
okHttpClient.newCall(request).enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
}
});
okHttpClient.newCall(request) 的步骤与同步请求相同,都是生成一个 RealCall 对象,直接看它的 enqueue 方法。
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
方法中关键的代码是。
client.dispatcher().enqueue(new AsyncCall(responseCallback));
调用了 okHttpClient 对象的 dispatcher 的 enqueue 方法,传入了回调方法的参数。看一下这个 enqueue 方法中做了什么。
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
在此方法中,先是判断正在运行的异步操作是否大于最大的请求数以及同一个 host 是否已经到达最大的请求数,如果都满足,则将这个异步请求放入列表中并执行,否则就将它放入等待执行的队列中,需要关注的代码是。
executorService().execute(call);
来看一下这个 executorService() 是干什么的,看一下它的代码。
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
可以看出这个方法是用来获得一个线程池的,所以调用 execute(call) 来执行线程。看一下这个 call 是什么类型的,它应该是对我们之前的异步请求进行了包装,看一下代码。
final class AsyncCall extends NamedRunnable {
private final Callback responseCallback;
AsyncCall(Callback responseCallback) {
super("OkHttp %s", redactedUrl());
this.responseCallback = responseCallback;
}
String host() {
return originalRequest.url().host();
}
Request request() {
return originalRequest;
}
RealCall get() {
return RealCall.this;
}
@Override protected void execute() {
boolean signalledCallback = false;
try {
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException e) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
eventListener.callFailed(RealCall.this, e);
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
}
AsyncCall 是继承自 NamedRunnable ,所以他可以被线程池执行,在它的 execute() 方法中,我们看到了熟悉的东西。
Response response = getResponseWithInterceptorChain();
这样就可以知道了,异步请求与同步请求一样,最后也是通过拦截器链来获取请求结果。
到这里, OkHttp 的同步请求、异步请求的流程就都理清了。接下来看一下 Retrofit 的源码。
Retrofit
关于 Retrofit,之前有写过一篇文章 Android Retrofit2简单使用学习,可以了解一下。下面按着步骤看一下它的源码。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.douban.com/v2/")
.build();
首先需要创建一个 Retrofit 对象,对象的创建是通过 Retrofit 的内部类 Builder 来创建,这里设置了 baseUrl,还可以设置其他的参数,如果不设置则会采取默认的配置,但是 baseUrl 是不可缺少的。可以看一下 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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
可以看到,除了 baseUrl,其他的 callFactory 、converterFactories 等参数,都为我们设置了默认值,callFactory 默认是使用 OkHttpClient,最后是利用这些参数,调用了 Retrofit 的带参构造函数,返回了一个 Retrofit 对象。 下一步是创建请求的代理对象。
BookService bookService = retrofit.create(BookService.class);
BookService 是自己编写的接口,用于写一些请求的接口,方法参数等都定义在这里。
public interface BookService {
@GET("book/{id}")
Call<ResponseBody> getBook(@Path("id") int id);
}
这里需要看 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.adapt(okHttpCall);
}
});
}
可以看出是使用了动态代理的方法。调用了 loadServiceMethod 方法获取之前定义的网络接口里的方法。看一下 loadServiceMethod 方法。
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;
}
此方法返回的是 ServiceMethod 对象, 是通过 new ServiceMethod.Builder<>(this, method).build() 来获得的。我们来看一下这个方法里做了些什么。
public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
if (!hasBody) {
if (isMultipart) {
throw methodError(
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}
return new ServiceMethod<>(this);
}
首先是 createCallAdapter() 方法。
private CallAdapter<T, R> createCallAdapter() {
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
这个方法里主要的工作是获取 method 的类型和注解,然后调用 retrofit.callAdapter(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;
}
}
StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
.append(returnType)
.append(".\n");
if (skipPast != null) {
builder.append(" Skipped:");
for (int i = 0; i < start; i++) {
builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
可以看出它是通过 for 循环在我们之前设置的 callAdapterFactories 里寻找适合方法的适配器,并返回,如果没有对应的就报错。
下一步分析 build 中的 createResponseConverter 方法。
public <T> Converter<ResponseBody, T> 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<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
可以看出与 createCallAdapter() 方法类似,是用来获取相应的转换器。
loadServiceMethod 方法简单的来说,就是把之前带有注解的方法转为,配置完网络请求参数的方法。
下一步是创建 okHttpCall 对象。
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
创建完成之后,调用方法。
serviceMethod.adapt(okHttpCall);
在我们之前设置好的CallAdapter中可以看到 adapt 方法。
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
而 ExecutorCallbackCall 中的实现看一下。
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> 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<T> 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<T> 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<T> clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override public Request request() {
return delegate.request();
}
}
在这个类中看到熟悉的 enqueue 和 execute ,而 delegate 就是我们之前设置的 okHttpCall 对象。看一下 OkHttpCall 这个类含有的对象。
final class OkHttpCall<T> implements Call<T> {
private final ServiceMethod<T, ?> serviceMethod;
private final @Nullable Object[] args;
private volatile boolean canceled;
@GuardedBy("this")
private @Nullable okhttp3.Call rawCall;
@GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
private @Nullable Throwable creationFailure;
@GuardedBy("this")
private boolean executed;
可以看到有一个 okhttp3.Call 类型的对象,而所有的请求,都是由这个 okhttp3.Call 来执行。因此,下面的步骤的源码就是 OkHttp 请求的源码。
BookService bookService = retrofit.create(BookService.class);
Call<ResponseBody> call = bookService.getBook(1220562);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
String s = response.body().string();
Log.e(TAG, s);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, t.toString());
}
});
剩下的流程就是通过动态代理获得上述的对象,再进行执行,获得请求结果。
以上就是 Retrofit 源码部分。
最后
阅读源码可以帮助我们更好的理解框架的原理,在阅读的过程中还可以学到很多设计模式相关的知识,在日后自己的编码中可以借鉴学习。读了这两个热门框架的源码,(虽然只读了表面的流程,更深层次的代码并没有深入地去读,当然把所有实现都去读一遍是不太可能的),自己的感觉就是,造这些轮子的人太牛了,还有,读源码太累了 :)