通常使用Retrofit,如下:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.wanandroid.com/")
.client(builder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
new Retrofit.Builder()
public Builder() {
this(Platform.get());
}
Builder(Platform platform) {
this.platform = platform;
// 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());
}
Platform.get()
static Platform get() {
return PLATFORM;
}
PLATFORM
private static final Platform PLATFORM = findPlatform();
findPlatform()
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
//目前是在Android里面应用,所以走的这个分支
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
new Android()
//Android类是继承自Platform的,重写了Platform的两个方法
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 {
//这里Handler初始化用的是getMainLooper(),说明此Handler最后是运行在UI线程的
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
baseUrl这儿略过,只是设置一个基础的HttpUrl,不做深入研究。
client()方法:
public Builder client(OkHttpClient client) {
return callFactory(checkNotNull(client, "client == null"));
}
//在这里可能会有疑问,如果在new Retrofit.Builder对象的时候,没有调用Client方法,
//那么岂不是没有可用于发送网络请求的OkHttpClient了?这个问题接着往下看会做解释
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}
Client方法其实就是给Retrofit.Builder对象设置一个OkHttpClient对象,用于后续网络请求时使用,Retrofit其实就是对OkHttp的封装;在这里可能会有疑问,如果在new Retrofit.Builder对象的时候,没有调用Client方法,那么岂不是没有可用于发送网络请求的OkHttpClient了?这个问题接着往下看就会明白,其实是在Retrofit.Builder的build方法中,发现client为null的时候,就会new 一个OkHttpClient出来。
下面要上关键点了,主要看addCallAdatperFactory和addConvertFactory,搞清楚这两个东西的调用和来源,基本上Retrofit的原理就清晰很多了:
addCallAdatperFactory和addConvertFactory:
private final List converterFactories = new ArrayList<>();
private final List adapterFactories = new ArrayList<>();
public Builder addConverterFactory(Converter.Factory factory) {
//把ConvertFactory添加到一个List集合中,集合会在Retrofit.Builder的build方法中被使用
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
//把CallAdatperFactory添加到一个List集合中,集合会在Retrofit.Builder的build方法中被使用
adapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
接下来看Retrofit.Builder的build方法:
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
//如果在调用build()方法之前,并没有调用client方法,那么在此处会new 一个OkHttpClient
//用于后续做网络请求
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
//默认的Executor是DefaultCallbackExecutor由于是在Android平台使用,
//这里是Platformat的内部类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 {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}*/
//返回的是MainThreadExecutor,也就是说callbackExecutor,其实就是类MainThreadExecutor的对象实例
//如果调用execute方法同步执行网络请求,那么就是执行的MainThreadExecutor的execute方法,通过创建UI线程的Handler对象,
//将execute的任务post出来,然后执行。
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
}
到这里,Retrofit对象就创建完毕了,接下来该是生成请求接口对象实例了,一般都是调用Retrofit.create方法:
//生成网络请求接口实例
//这里需要思考一个问题,Java中Interface是没有办法实例化的,那么Retrofit是通过怎样的方式生成Interface实例对象的呢,答案就是动态代理
WanAndroidApi wanAndroidApi = retrofit.create(WanAndroidApi.class);
//Retrofit.java
public T create(final Class 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, Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
//如果调用的方法是Object类的方法,比如wait,toString,hashCode等,那么不做额外处理,直接调用返回
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//跟踪代码可知,platform的isDefaultMethod返回false,故此分支进不去
/*
boolean isDefaultMethod(Method method) {
return false;
}
*/
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//最终会执行loadServiceMethod方法
ServiceMethod
看loadServiceMethod方法:
//Retrofit.java
ServiceMethod, ?> loadServiceMethod(Method method) {
//如果缓存里面有,那么直接返回
ServiceMethod, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
//若缓存中没有当前method对应的对象(也就是ServiceMethod.Builder对象),new一个并将其添加到缓存
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
接着看ServiceMehtod.Builder的build方法:
//ServiceMethod.java
public ServiceMethod build() {
//创建生成CallAdapter
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也就是Gson,xml等格式转换器
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
......
return new ServiceMethod<>(this);
}
//ServiceMethod.java
private CallAdapter createCallAdapter() {
//这里的method其实就是,当前调用自定义网络请求Interface中的方法
//returnType就是当前方法的返回值类型,比如Call、Obserable等
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
//如果没有返回是,也就是void,抛出异常
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
//获取当前调用方法的注解,比如@GET、@POST、@MultiPart等
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
//调用retrofit的callAdapter方法生成CallAdapter对象
return (CallAdapter) 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);
}
}
//Retrofit.java
public CallAdapter, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter, ?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = adapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
......
throw new IllegalArgumentException(builder.toString());
}
注意
在nextCallAdapter方法中,这里的adapterFactories,就是创建Retrofit对象的时候会调用addCallAdapterFactory方法,在addCallAdapterFactory方法中,会将添加的CallAdapterFactory对象,添加到adapterFactories这个list中
public Builder addCallAdapterFactory(CallAdapter.Factory factory) { adapterFactories.add(checkNotNull(factory, "factory == null")); return this; }
那么有个疑问,如果在调用Retrofit.Builder的build方法之前没有调用addCallAdapterFactory方法,adapterFactories岂不是为null了,其实如果adapterFactories为null,那么会在Retrofit.Builder的build方法中添加默认的,在build方法中,有如下代码段:
// Make a defensive copy of the adapters and add the default Call adapter. List
adapterFactories = new ArrayList<>(this.adapterFactories); //在此处,不论在build之前有没有调用addCallAdapterFactory方法,此处都会再添加一个默认CallAdapter adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); // Make a defensive copy of the converters. List converterFactories = new ArrayList<>(this.converterFactories); //new Retrofit对象的时候会将新创建的adapterFactories传入,所以不用担心没有初始化的问题 return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly);
那么接着来看nextCallAdapter方法,在for循环中返回了CallAdapter对象,如下面代码段:
//Retrofit.java,nextCallAdapter方法
int start = adapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
从前面代码可知:在callAdapter方法中调用nextCallAdpater,
public CallAdapter, ?> callAdapter(Type returnType, Annotation[] annotations) { return nextCallAdapter(null, returnType, annotations); }
nextCallAdapter第一个参数为null,说明skipPast为null,那么int start = adapterFactories.indexOf(skipPast) + 1;start的值为0,因为adapterFactories这个列表中并没有null对象,所以adapterFactories.indexOf(skipPast)的值为-1,-1+1=0,所以start值为0
所以for循环中i值其实是从0开始的,接下来就分为两种情况了:
1,在调用Retrofit.Builder的build方法之前,就已经调用了addAdapterFactory方法添加了Adapter,那么adapterFactories这个list中的第一个元素,也就是下标为0的元素(也就是adapterFactories.get(0)),就是调用addAdapterFactory添加的Adapter,比如像文章开头处创建Retrofit的方式:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://www.wanandroid.com/") .client(builder.build()) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build();
那么这里的adapterFactories.get(0)就是RxJava2CallAdapterFactory.create()。
接下来,看下如果添加了调用了addAdapterFactory方法,在创建Retrofit对象的时候调用如下方法:addCallAdapterFactory(RxJava2CallAdapterFactory.create()):
在Retrofit的create方法的动态代理中,最终返回的的是return serviceMethod.callAdapter.adapt(okHttpCall);看下这个流程:serviceMethod.callAdapter是CallAdapter
类型对象,前面已经讲过,callAdapter的初始化是在createCallAdapter()中,最终会调用到Retrofit.java的nextCallAdapter方法,CallAdapter, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this); 我们知道此处的adapterFactories这个list中获取的第一个不为null的CallAdapterFactory对象,就是我们自己通过addCallAdapterFactory添加的RxJava2CallAdapterFactory。
RxJava2CallAdapterFactory.create方法返回的对象是RxJava2CallAdapterFactory,然后RxJava2CallAdapterFactory的get方法返回的是RxJava2CallAdapter对象,接着看RxJava2CallAdapter的adapt方法,最终返回的就是Obserable,这就是Rxjava的Obserable被观察者。
有了Obserable对象,就可以调用Rxjava中Observer的observer方法和subscribeOn等方法,实现UI线程回调网络请求线程。
2,在调用Retrofit.Builder的build方法之前,没有调用addAdapterFactory,那么那么adapterFactories这个list中的第一个元素,就是在build方法中添加的platform.defaultCallAdapterFactory(callbackExecutor)
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
在nextCallAdapter的for循环中,如果拿到第一个Adapter,那么就直接return了,后续Adapter就是用的此处返回的。
默认的CallAdapter 是如下流程:
platform.defaultCallAdapterFactory(callbackExecutor)--》new ExecutorCallAdapterFactory(callbackExecutor);--》ExecutorCallAdapterFactory的get方法,get方法中return的时候,new CallAdapter,new 出来的CallAdapter重写了adapt方法,adapt方法返回new ExecutorCallbackCall<>(callbackExecutor, call);--》ExecutorCallbackCall是继承自Call
的,它里面分别实现了同步请求execute方法和异步请求enqueue方法。 这里注意
同步请求execute方法是用了静态代理,delegate.execute最终会转到,前面提到的Create方法里面动态代理的最后new 出来的OkHttpCall里面的execute()方法--》createRawCall()--》serviceMethod.callFactory.newCall,这里serviceMethod.callFactory就是okhttp3.Call.Factory--》builder.retrofit.callFactory(),这就是OkHttpClient,调用OkHttpClient的newCall方法执行网络请求。
异步请求enqueue方法中,也用了静态代理:
delegate.enqueue(new Callback
() { @Override public void onResponse(Call call, final Response 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); } } }); } 这里的callbackExecutor其实就是前面提到的Platform的内部类Android中的MainThreadExecutor
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 { private final Handler handler = new Handler(Looper.getMainLooper()); @Override public void execute(Runnable r) { handler.post(r); } } }
delegate.enqueue也是最终转到OkHttpCall中的enqueue方法(跟同步的execute是同样的),最终调用OkHttpclient的newCall方法执行请求。
callbackExecutor.execute执行的就是MainThreadExecutor的execute方法,Handler是初始化在main线程的,这儿就理解了回调为什么会在UI线程。
在Retrofit.Builder的构造方法中,会首先添加一个默认的ConvertFactory,converterFactories.add(new BuiltInConverters());
如果调用addConvertFactroy方法添加了ConvertFactory,也会将这些ConvertFactory添加到converterFactories这个list中
那么在Retrofit.Builder的build方法中,在new Retrofit的时候传入这个converterFactories,
ConvertFactory的流程比较简单,这里就不仔细展开说明了。
就是在Retrofit的requestBodyConverter和reponseBodyConverter中,分别会调用nextRequestBodyConverter和nextResponseBodyConverter方法,这两个next方法中会获取converterFactories这个list中添加的Convert.Factory对象,具体的调用是在ServiceMethod的toResponse中调用;ServiceMethod的toResponse方法是在OkHttpCall的parseResponse方法中调用的,而parseResponse分别在OkHttpCall的enqueue和execute两个方法的参数Callback中的onResponse中调用的,也就是说,在onResponse方法回调的时候,就将返回的数据流序列化为java对象了。
结束。