本文参考诸多博客,以及自己看源码分析。内容并非完全原创,写博客的目的只是让自己能够用文字去描述一遍源码实现,让自己总结一下。
先了解一下Retorift的使用步骤
1.创建retrofit实例
2.创建网络请求接口实例
3.进行网络请求
4.处理网络请求回来的数据
那么接下来就开始根据使用步骤一步一步分析
1.创建retrofit实例
创建Retrofit实例对象
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(AppUrl.getHttpUrl())
.build();
retrofit使用的是建造者模式,可以看出,build()以后返回的是Retrofit实例对象,所以肯定会去调用构造方法,所以先看一下Retrofit的构造方法
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
Executor callbackExecutor, boolean validateEagerly) {
// 网络请求器的工厂,默认使用okhttp
this.callFactory = callFactory;
// 网络请求的url地址
this.baseUrl = baseUrl;
// 数据转换器工厂的集合
this.converterFactories = unmodifiableList(converterFactories);
//网络请求适配器工厂作用:生产网络请求适配器(CallAdapter)
this.adapterFactories = unmodifiableList(adapterFactories);
// 回调方法执行器
this.callbackExecutor = callbackExecutor;
//是否提前对业务接口中的注解进行验证转换的标志位
this.validateEagerly = validateEagerly;
}
主要初始化了以上参数,就先大概熟悉一下上面几个参数具体是有什么作用
接下来根据上面的参数一个一个的进行分析
CallAdapter(网络请求执行器Call的适配器)
callAdapter默认是使用OkHttpCall,以下代码来自Platform内部实现
在Retrofit中提供了四种CallAdapterFactory: ExecutorCallAdapterFactory(默认)、GuavaCallAdapterFactory、Java8CallAdapterFactory、RxJavaCallAdapterFactory
接下来就继续分析Builder这个类,部分代码已经删掉了,留下一些代码分析
public static final class Builder {
private Platform platform;
private okhttp3.Call.Factory callFactory;
private HttpUrl baseUrl;
private List<Converter.Factory> converterFactories = new ArrayList<>();
private List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
private Executor callbackExecutor;
private boolean validateEagerly;
Builder(Platform platform) {
this.platform = platform;
converterFactories.add(new BuiltInConverters());
}
//会调用这个无参构造,this再去调用有参构造
public Builder() {
this(Platform.get());
}
那就先看看Platform里面都
class Platform {
// 将findPlatform()赋给静态变量
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
//以下代码可以看出,支持3个平台:Android平台、Java平台、IOS平台
private static Platform findPlatform() {
try {
// Class.forName(xxx.xx.xx)的作用:要求JVM查找并加载指定的类(即JVM会执行该类的静态代码段)
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
// 如果是Android平台,就创建一个Android对象返回
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
//java平台
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
//ios平台
try {
Class.forName("org.robovm.apple.foundation.NSObject");
return new IOS();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
因为我们是Android平台,所以看一下Android的内部实现
static class Android extends Platform {
//创建默认的网络请求适配器工厂
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
// 返回一个默认的回调方法执行器
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
// 获取Android主线程绑定的Handler
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
再分析一下GsonConverterFactory.create()
public final class GsonConverterFactory extends Converter.Factory {
public static GsonConverterFactory create() {
//创建Gson对象
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
//创建了包含Gson对象实例的GsonConverterFactory
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
}
}
从上面这段代码可以看出,GsonConverterFactory.create()实际上就是创建了一个含有Gson对象的GsonConverterFactory,再看看addConverterFactory的内部实现,实际上就是把GsonConverterFactory添加到了数据转换器工厂的集合当中
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
再来分析一下baseUrl执行了什么操作,baseUrl(“www.baidu.com”)
public Builder baseUrl(String baseUrl) {
//判断url是否为空
checkNotNull(baseUrl, "baseUrl == null");
//转换为Okhttp的HttpUrl类型
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
//检查URL参数是不是以"/"结尾
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
由此得知,url会转换为Okhttp的HttpUrl类型,并且Url一定要以"/"结尾,否则会抛出异常。
最后再分析一下,.build()方法。
public Retrofit build() {
//判断请求url地址是否为空
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
//如果没有指定,默认用OkHttpClient
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//如果没有指定,会默认使用MainThreadExecutor
//之前已经判断了当前环境是Android,而继承自Platform的Android里面已经提供了默认的
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
//添加网络请求适配器工厂到集合当中,默认适配器工厂(ExecutorCallAdapterFactory)添加到集合最后
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
//数据转换器工厂 1.默认的数据转换工厂 2.自定义的数据转换工厂
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
//最终返回Retrofit的对象,并传入已经配置好的成员变量
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
2.创建网络请求接口实例
//定义接收网络数据的类
public interface HttpService {
// app版本检查
//注解GET:采用Get方法发送网络请求
@GET("app/version/get-newversioninfo?versionCode=1")
// 接受网络请求数据的方法
Call<JavaBean> newVersionInfo();
}
HttpService httpService = retrofit.create(HttpService.class);
Call<JavaBean> call = httpService.newVersionInfo();
接下来就看看retrofit.create(service)到底做了什么。
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() { // 将代理类的实现交给 InvocationHandler类作为具体的实现
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, Object... args)
throws Throwable {
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//主要就是一下三行代码的实现,下面再具体分析这三行代码
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
private void eagerlyValidateMethods(Class<?> service) {
//获取当前系统环境
Platform platform = Platform.get();
//获取本类中的所有方法,包含private,protected以及默认权限
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {
//将传入的ServiceMethod对象加入LinkedHashMap<Method, ServiceMethod>集合
loadServiceMethod(method);
}
}
}
ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result;
synchronized (serviceMethodCache) {
//先通过key获取ServiceMethod(以Method为键将该对象存入LinkedHashMap集合中)
result = serviceMethodCache.get(method);
//如果ServiceMethod为空,则创建ServiceMethod并添加
if (result == null) {
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
前面提到invoke有三行代码,现在开始分析这三行代码,loadServiceMethod在上面已经大概添加了注解了,继续看loadServiceMethod方法中的new ServiceMethod.Builder(this, method).build() 具体内部实现
final class ServiceMethod<T> {
static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*";
static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}");
static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM);
// 网络请求工厂
final okhttp3.Call.Factory callFactory;
//网络请求适配器工厂
final CallAdapter<?> callAdapter;
// 网络请求地址
private final HttpUrl baseUrl;
// Response内容转换器
private final Converter<ResponseBody, T> responseConverter;
// 网络请求的Http方法
private final String httpMethod;
// 网络请求的相对地址
private final String relativeUrl;
// 网络请求的http请求头
private final Headers headers;
// 网络请求的http报文body的类型
private final MediaType contentType;
private final boolean hasBody;
private final boolean isFormEncoded;
private final boolean isMultipart;
private final ParameterHandler<?>[] parameterHandlers;
ServiceMethod(Builder<T> builder) {
this.callFactory = builder.retrofit.callFactory();
this.callAdapter = builder.callAdapter;
this.baseUrl = builder.retrofit.baseUrl();
this.responseConverter = builder.responseConverter;
this.httpMethod = builder.httpMethod;
this.relativeUrl = builder.relativeUrl;
this.headers = builder.headers;
this.contentType = builder.contentType;
this.hasBody = builder.hasBody;
this.isFormEncoded = builder.isFormEncoded;
this.isMultipart = builder.isMultipart;
this.parameterHandlers = builder.parameterHandlers;
}
}
通过上面的代码可以知道,SeviceMethod包含了网络请求的基本信息
再看看build的实现
public ServiceMethod build() {
// 根据网络请求接口方法的返回值和注解类型,从Retrofit对象中获取对应的网络请求适配器
callAdapter = createCallAdapter();
// 根据网络请求接口方法的返回值和注解类型,从Retrofit对象中获取该网络适配器返回的数据类型
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?");
}
// 根据网络请求接口方法的返回值和注解类型,从Retrofit对象中获取对应的数据转换器
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.");
}
//为方法中的每个参数创建一个ParameterHandler<?>对象并解析每个参数使用的注解类型
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);
}
private CallAdapter<?> 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.");
}
// 获取网络请求接口接口里的注解
// 此处使用的是@Get
Annotation[] annotations = method.getAnnotations();
try {
return 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);
}
}
private Converter<ResponseBody, T> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create converter for %s", responseType);
}
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
// 根据目标类型,利用 Gson#getAdapter 获取相应的 adapter
return new GsonResponseBodyConverter<>(gson, adapter);
}
// 做数据转换时调用 Gson 的 API 即可。
final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter<T> adapter;
GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
return adapter.read(jsonReader);
} finally {
value.close();
}
}
}