文档中对retrofit进行解读的时候可能会删减部分代码。
retrofit和okhttp
retrofit
是okhttp
进行的了封装,使用和调用更加简单方便,但是功能会有收窄。而okhttp
功能更多更强。
retrofit
源码解析
val retrofit = Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val service = retrofit.create(GithubService::class.java)
var repos = service.listRepos("octocat")
repos.enqueue(object : Callback<List<Repo>>{
override fun onFailure(call: Call<List<Repo>>, t: Throwable) {
}
override fun onResponse(call: Call<List<Repo>>, response: Response<List<Repo>>) {
tv.text = response.body()?.get(0)?.name ?: "不知道"
}
})
首先从repos
出发查看enqueue()
方法:
发现只是一个接口类中的一个方法:
void enqueue(Callback<T> callback);
移动到上一层实现:
retrofit.create(GithubService::class.java)
public <T> T create(final Class<T> service) {
validateServiceInterface(service);
return (T)
Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {service},
new InvocationHandler() {
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
在validateServiceInterface
中进行接口的校验,发现在return
中使用的是动态代理模式,那么着重看一下invoke
方法,在最后执行了loadServiceMethod(method).invoke(args
),其中invoke
方法是一个抽象方法。那么就看上一层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 = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
这里着重看一下ServiceMethod
的生成,也就是ServiceMethod.parseAnnotations(this, method)
方法。
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
在最后实现的是HttpServiceMethod
类中的parseAnnotations
方法。但是进入到HttpServiceMethod
类中发现是继承了ServiceMethod
类,
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT>
之前的动态代理有个invoke
方法,HttpServiceMethod
有可能实现了invoke
方法。那么可以先看一下invoke
方法的实现,先将parseAnnotations
方法搁置起来。
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
最后由于adapter
方法也是抽象方法
protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
所以可以看一下OkHttpCall
是怎么创建的,
final class OkHttpCall<T> implements Call<T>
发现OkHttpCall
是实现了Call
接口,所以这个类又是final
类,所以肯定会有enqueue
的实现方法。
public void enqueue(final Callback<T> callback) {
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (call == null && failure == null) {
//实现了okhttp3.Call
call = rawCall = createRawCall();
}
}
call.enqueue(
//这里用到的是okhttp3的CallBack
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
response = parseResponse(rawResponse);
//请求完成之后用的是方法参数的Callback
callback.onResponse(OkHttpCall.this, response);
}
@Override
public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
callback.onFailure(OkHttpCall.this, e);
}
});
}
createRawCall()
方法是创建okhttp
的请求,最后在分析。
可以看到真正请求接口还是okhttp
的请求,但是callback
还是在线程中,接下来如何转到主线程的,继续回到adapter
方法。
因为HttpServiceMethod
实现了invoke
方法,所以放弃了HttpServiceMethod
的parseAnnotations
方法,但是parseAnnotations
又返回了HttpServiceMethod
类,并且adapter
方法又是调用的自己类的方法,所以看一下parseAnnotations
返回值,看一下返回值是否有adapter
方法实现:
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
//判断是否是kotlin挂起函数
if (!isKotlinSuspendFunction) {
//返回CallAdapted。
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForResponse<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForBody<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}
在返回中看到如果不是kotlin
挂起函数就返回了CallAdaptered
类。
CallAdapted
类实现了HttpServiceMethod
,并实现了adapter
方法:
//CallAdapted构造函数
CallAdapted(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
//传入了callAdapter
this.callAdapter = callAdapter;
}
//实现了adapt方法
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
//然后调用callAdapter的adapt方法,将OkHttpCall传进来。
return callAdapter.adapt(call);
}
然后在parseAnnotations
方法中,实现了CallAdapted
类,其中callAdapter
的创建是createCallAdapter
方法:
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
try {
//noinspection unchecked
return (CallAdapter<ResponseT, ReturnT>) 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
直到Retrofit
类中nextCallAdapter
方法:
public CallAdapter<?, ?> nextCallAdapter(
@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
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
集合中返回了CallAdapter
,那么看一下callAdapterFactories
是怎样将CallAdapter
放入到集合中的:
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类
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);
//将CallAdapter放入到callAdapterFactories中。
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories =
new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// 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);
converterFactories.addAll(platform.defaultConverterFactories());
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
查看defaultCallAdapterFactories
方法:
platform.defaultCallAdapterFactories(callbackExecutor)
在platform
类中,defaultCallAdapterFactories
方法返回了DefaultCallAdapterFactory
工厂类,在DefaultCallAdapterFactory
类中的get
方法:
@Override
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException(
"Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
}
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
final Executor executor =
Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
? null
: callbackExecutor;
return new CallAdapter<Object, Call<?>>() {
@Override
public Type responseType() {
return responseType;
}
@Override
public Call<Object> adapt(Call<Object> call) {
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}
};
}
最后返回了CallAdapter
类实现了CallAdapter
的adapter
方法,并实例化了ExecutorCallbackCall
类,其中call
参数就是OkHttpCall
。ExecutorCallbackCall
实现了Call
接口,并且将okhttpCall
包裹进来,实现了enqueue
方法:
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
//delegate就是okhttpcall并请求接口
delegate.enqueue(
new Callback<T>() {
@Override
public void onResponse(Call<T> call, final Response<T> response) {
//请求成功之后执行callbackExecutor.execute
callbackExecutor.execute(
() -> {
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(() -> callback.onFailure(ExecutorCallbackCall.this, t));
}
});
}
请求成功之后执行callbackExecutor.execute
方法,callbackExecutor
的实例化过程:
platform.defaultCallbackExecutor();
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
创建MainThreadExecutor
之后,启动handler
放在主线程,然后发送消息。
总结:所以var repos = service.listRepos("octocat")
,repos
是ExecutorCallbackCall
类,并且里面包裹了OkHttpCall
,而okHttpcall
主要负责的是请求网络,MainThreadExecutor
则转到了主线程。
最后看一下是怎么创建okhttp
的请求的createRawCall
:
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
其中requestFactory
是在创建okhttpcall
中传入的,所以在HttpServiceMethod
类中查找requestFactory
,最后追溯到ServiceMethod
创建的requestFactory
:
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
if (!hasBody) {
if (isMultipart) {
throw methodError(
method,
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError(
method,
"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, lastParameter = parameterCount - 1; p < parameterCount; p++) {
parameterHandlers[p] =
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
}
if (relativeUrl == null && !gotUrl) {
throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError(method, "Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError(method, "Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError(method, "Multipart method must contain at least one @Part.");
}
return new RequestFactory(this);
}
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
} else if (annotation instanceof HEAD) {
parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
} else if (annotation instanceof PATCH) {
parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
} else if (annotation instanceof POST) {
parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
} else if (annotation instanceof PUT) {
parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
} else if (annotation instanceof OPTIONS) {
parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
} else if (annotation instanceof HTTP) {
HTTP http = (HTTP) annotation;
parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
} else if (annotation instanceof retrofit2.http.Headers) {
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError(method, "@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
在parseMethodAnnotation
方法将请求方法和value
记录下来,parseParameter
再到parseParameterAnnotation
方法将具体的参数记录。最后在create
通过build
方法生成okhttp
请求。