一、使用
接口类
public interface ApiServer {
String baseUrl="https://wanandroid.com/";
//https://wanandroid.com/wxarticle/chapters/json
@GET("wxarticle/chapters/json")
Call<ResponseBody> getChapters();
}
构建Retrofit对象 最原始的 最简单 最原始的请求 没有添加 addCallAdapterFactory和addConverterFactory
// 构建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiServer.baseUrl)
.build();
// 创建api接口对象. //核心
ApiServer apiServer = retrofit.create(ApiServer.class);
// Create a call instance for looking up Retrofit contributors.
// 调用对应接口方法
Call<ResponseBody> chapters = apiServer.getChapters();
// 发起请求 原始结果
ResponseBody body = chapters.execute().body();
添加GsonConverter转换器解析结果 可以自定义其他格式的解析器
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiServer.baseUrl)
.addConverterFactory(GsonConverterFactory.create()) //处理请求结果
.build();
添加CallAdapter 请求适配器 自定义请求适配器 可以在发起请求前做一些事情 设置多个时 要注意拦截类型
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiServer.baseUrl)
.addCallAdapterFactory(new MyCallAdapterFactory()) //在请求发起前干事情
.addConverterFactory(GsonConverterFactory.create()) //处理请求结果
.build();
自定义的CallAdapter 可以参考 DefaultCallAdapterFactory
static class MyCallAdapterFactory extends CallAdapter.Factory {
@Override public @Nullable CallAdapter<?, ?> get(
final Type returnType, Annotation[] annotations, Retrofit retrofit) {
//注意拦截返回类型 后面源码分析会看到相应逻辑
if (getRawType(returnType) != Call.class) {
return null;
}
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return getParameterUpperBound(0, (ParameterizedType) returnType);
}
@Override public Call<Object> adapt(Call<Object> call) {
System.out.println("请求前");
return call;
}
};
}
}
比较简单的使用样例 其他的各种注解 参考 官方文档
二、源码分析
源码分析 涉及动态代理 、适配器模式、建造者模式
1、首先分析 Retrofit的创建过程 通过建造者模式 构建的
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiServer.baseUrl)
.addCallAdapterFactory(new MyCallAdapterFactory()) //在请求发起前干事情
.addConverterFactory(GsonConverterFactory.create()) //处理请求结果
.build();
1、创建Retrofit.Builder对象 这里涉及到平台问题 这里是Android平台 网络回调UI线程
public Builder() {
this(Platform.get());
}
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
return new Platform(true);
}
......
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@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);
}
}
}
}
2、这里baseUrl 有个小细节 需要注意一下 baseUrl一定是以"/"结尾的 源码会做校验 直接抛异常
public Builder baseUrl(HttpUrl baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
3、其他的addCallAdapterFactory、addConverterFactory都是添加到相应的集合中
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
4、组装 Retrofit 涉及到创建okhttp 请求OkHttpClient,android平台默认回调在主线程 、添加callAdapter和处理结果的转换器 Converter ,最后这两个集合都转换成只读集合
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();//因为真正请求网络是用的okhttp框架 请求client
}
//回调线程环境
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
//Android平台默认情况是在Android 主线程回调
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.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);
}
2、分析核心 接口转换成具体实现类ApiServer apiServer = retrofit.create(ApiServer.class);
涉及动态代理 、适配器模式
将接口的所有方法 包装成ServiceMethod 的子类 HttpServiceMethod
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);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//将方法 包装成 ServiceMethod 实际是包装成HttpServiceMethod 然后调用invoke
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
包装的过程 缓存方法 避免每次去反射 耗性能
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;
}
解析和处理请求方法的各种注解 分两步
1、通过注解 构建 请求对象
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//解析请求 处理各种注解 GET POST HEAD 等
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);
}
//方法返回类型不能是 void
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
核心方法 RequestFactory 类中
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;
}
}
2、分析 HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
去掉一些不重要的代码 ,主要是收集CallAdapter 和 Converter转换器 最后都会调用到
retrofit类里的nextCallAdapter方法和nextResponseBodyConverter方法 ,最后返回
new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
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) {
......
} else {
adapterType = method.getGenericReturnType();
}
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
......
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
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);
}
}
nextCallAdapter方法和nextResponseBodyConverter方法 在自定义CallAdapter和Converter时返回null相当于无效
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
Objects.requireNonNull(returnType, "returnType == null");
Objects.requireNonNull(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;
}
}
......
throw new IllegalArgumentException(builder.toString());
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
Objects.requireNonNull(type, "type == null");
Objects.requireNonNull(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;
}
}
......
throw new IllegalArgumentException(builder.toString());
}
最后返回一个 new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter); 对象
CallAdapted 是继承 HttpServiceMethod的
在动态代理的部分 ,包装成 HttpServiceMethod 后 调用 invoke
最后call 的实现类就是 OkHttpCall ,adapt会逐层调用 callAdapter的adapt方法 包括自定义的 所以自定义的一定要返回call ,否则会中断请求
@Override final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
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) {
return callAdapter.adapt(call);
}
}
分析 Call chapters = apiServer.getChapters();
apiServer.getChapters()会返回一个OkHttpCall对象
执行请求时 chapters.execute() 即执行 OkHttpCall里的execute()
真正的网络请求 是okhttp框架去请求
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException | Error e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());
}
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);
}
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
//结果格式转换
T body = responseConverter.convert(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;
}
}
至此主流程完成 核心模块 在动态代理上