阅读源码我们从代码的调用开始分析。如有错误请指正,不喜勿喷!
1.依赖库
dependencies{
//>>>>>>>>>>>> retrofit 引用retrofit OkHttp也会被 自动加入
implementation("com.squareup.retrofit2:retrofit:2.9.0")
//看需要添加 RxJava
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
//看需要添加 切换到主线程
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
//implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
//看需要添加
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
//看需要添加 日志的拦截器
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.6'
//>>>>>>>>>>>> retrofit
}
2.创建Retrofit
val retrofit = Retrofit.Builder().build()
我们现在来看下Buidler这个类
public static final class Builder {
//运行平台 platform =Android()
private final Platform platform;
//OkHttpClient 对象
private @Nullable okhttp3.Call.Factory callFactory;
//baseUrl 通过 Builder().parse(null, this).build() 构建HttpUrl对象
private @Nullable HttpUrl baseUrl;
//数据转换器集合
private final List<Converter.Factory> converterFactories = new ArrayList<>();
//Call适配器集合 如转换成RxJava Observable<T>
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
//线程切换 如没设置默认是MainThreadExecutor()通过handler切换到主线程
private @Nullable Executor callbackExecutor;
//true:提前对接口方法进行解析
private boolean validateEagerly;
Builder(Platform platform) {
this.platform = platform;
}
public Builder() {
//判断运行平台
this(Platform.get());
}
.....
}
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
return "Dalvik".equals(System.getProperty("java.vm.name"))
? new Android() //Android平台
: new Platform(true);
}
}
class Android extends Platform {
....
@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到主线程
handler.post(r);
}
}
}
接下来看下 build()做什么
public Retrofit build() {
...
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
//默认 MainThreadExecutor()
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.Factory的实现是 DefaultCallAdapterFactory(callbackExecutor)
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);
}
3.网络接口实例的创建
interface IServerAPI {
@GET("users/{username}")
fun getUser(@Path("username") username: String?): Call<User>
}
val iServerAPI = reterfit.create(IServerAPI::class.java)
现在我们来看下create到底做什么?传入接口 给我们返回一个对象。
public <T> T create(final Class<T> service) {
//接口校验
validateServiceInterface(service);
return (T)
Proxy.newProxyInstance(//动态反射
service.getClassLoader(),
new Class<?>[] {service},
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override
public @Nullable 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);
}
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
对传入的接口信息 进行校验 我们看下都校验了什么 validateServiceInterface(service)
private void validateServiceInterface(Class<?> service) {
//如果不是接口就抛出异常
if (!service.isInterface()) {
throw new IllegalArgumentException("API declarations must be interfaces.");
}
Deque<Class<?>> check = new ArrayDeque<>(1);
check.add(service);
while (!check.isEmpty()) {
Class<?> candidate = check.removeFirst();
//不能是泛型接口
if (candidate.getTypeParameters().length != 0) {
StringBuilder message =
new StringBuilder("Type parameters are unsupported on ").append(candidate.getName());
if (candidate != service) {
message.append(" which is an interface of ").append(service.getName());
}
throw new IllegalArgumentException(message.toString());
}
Collections.addAll(check, candidate.getInterfaces());
}
//初始化的时候默认是false 默认是不执行的
if (validateEagerly) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
loadServiceMethod(method);
}
}
}
}
那么我们看下这个validateEagerly=true的时候 loadServiceMethod(method) 执行些什么操作
ServiceMethod<?> loadServiceMethod(Method method) {
//缓存中获取ServiceMethod
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
//解析接口中的方法 封装ServiceMethod 缓存起来
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
我们现在看下这个ServiceMethod.parseAnnotations(this, method)是怎么解析的
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
...
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
接着调用RequestFactory.parseAnnotations(retrofit, method)
final class RequestFactory {
//接口方法
private final Method method;
//https://www.xx.xxx/ 封装对象
private final HttpUrl baseUrl;
//请求方式 GET、POST...
final String httpMethod;
//网络请求相对路径 user/info/
private final @Nullable String relativeUrl;
//协议头信息
private final @Nullable Headers headers;
//文件下载上传Media类型
private final @Nullable MediaType contentType;
//是否有Body
private final boolean hasBody;
//post 是否是表单数据
private final boolean isFormEncoded;
//post 一般用于文件请传送
private final boolean isMultipart;
//接口方法参数处理器
private final ParameterHandler<?>[] parameterHandlers;
//是否支持Kotlin
final boolean isKotlinSuspendFunction;
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
//RequestFactory 开始解析接口注解参数等信息
return new Builder(retrofit, method).build();
}
static final class Builder{
.....
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
//方法注解参数
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
//注解解析
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
// @FormUrlEncoded @Multipart 只能用 POST PATCH PUT
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).");
}
}
//解析方法参数
// Converter<F, T>.Factory中的Converter<?, String>.stringConverter(...)
// Converter<F, T>.Factory中的Converter<?, String>.requestBodyConverter(...)
//就在解析参数的时候被调用的
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;
}
}
.....
}
}
从代码可以看出RequestFactory使用了Builder模式来配置,有了RequestFactory,就接着往下看HttpServiceMethod
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
@Override
final @Nullable ReturnT invoke(Object[] args) {
//创建 OkHttpCall 封装了okhttp的网络请求
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
//适配的CallAapter
return adapt(call, args);
}
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;
Annotation[] annotations = method.getAnnotations();
Type adapterType;
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType =
Utils.getParameterLowerBound(
0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response<T>.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
} else {
// TODO figure out if type is nullable or not
// Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
// Find the entry for method
// Determine if return type is nullable or not
}
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
//方法返回类型如
//io.reactivex.rxjava3.core.Observable<com.learn.demo.retrofit.UserInfo>
adapterType = method.getGenericReturnType();
}
//从Retrofit.callAdapterFactories 集合中获取CallAdapter适配器
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
//解析返回类型的泛型类型
//如:io.reactivex.rxjava3.core.Observable<com.learn.demo.retrofit.UserInfo>
//callAdapter.responseType() -> class com.learn.demo.retrofit.UserInfo
Type responseType = callAdapter.responseType();
if (responseType == okhttp3.Response.class) {
throw methodError(
method,
"'"
+ getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (responseType == Response.class) {
throw methodError(method, "Response must include generic type (e.g., Response<String>)");
}
// TODO support Unit for Kotlin?
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
//Converter.Factory.responseBodyConverter(...)
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
//okHttpClient
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
//CallAdapted包装了 接口方法信息 ,okHttpClient responseConverter ,网络请求CallAdapter
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);
}
}
}
现在我们值接口方法是被封装到CallAdapter类中,我们现在回到create(..)
public <T> T create(final Class<T> service) {
...
return (T)
Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {service},
new InvocationHandler() {
...
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
//invoke(...) 返回接口方法的返回值CallAdapter对象
: loadServiceMethod(method).invoke(args);
}
});
}
loadServiceMethod(method).invoke(args);调用了ServiceMethod.invoke(...) -> HttpServiceMethod.invoke(...) -> CallAdapter.adapt(call, args) -> 到对应的CallAdapter的实现类中去执行。ExecutorCallbackCall 是默认的执行器,
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
CallAdapted(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
//默认是执行 DefaultCallAdapterFactory.adapt
// -> ExecutorCallbackCall
return callAdapter.adapt(call);
}
}
final class DefaultCallAdapterFactory extends CallAdapter.Factory{
@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);
}
};
}
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) {
Objects.requireNonNull(callback, "callback == null");
//delegate 是okHttpCall
delegate.enqueue(
new Callback<T>() {
@Override
public void onResponse(Call<T> call, final Response<T> response) {
//默认是 MainThreadExecutor 通过Handler 切换到主线程
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));
}
});
}
紧接OkHttpCall的enqueue
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(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 {
//创建OkHttp 的 Call
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
//调用OKHttp 请求
call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
//通过 responseConverter.convert(...)
//转换请求回来的数据
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
@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) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}
到这里Retrofit的调用基本流程及完成了。