介绍
网络请求库Retrofit怎么用,我在文章安卓开发学习之Retrofit2.0的使用中已经说了,现在我们简单看一下源码
Retrofit的调用过程无非四步:构造Retrofit对象,获取请求接口对象,获取Call对象,执行请求。各步骤代码如下:
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
final IRequest request = retrofit.create(IRequest.class);
Call<Result> call = request.getResult("fy", "auto", "auto", "" + input);
call.enqueue(new Callback<Result>() {....});
下面,我一步一步看Retrofit是大概怎么实现的
build()和enqueue()
这两个联系很紧密,所以把他们俩合在一起说
先看new Retrofit.Builder()方法,点进去:
public Builder() {
this(Platform.get());
}
调用了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");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
...
}
可以看到,如果我们是在安卓开发中构造的Retrofit,它就是通过反射获取安卓系统的Build类,返回一个Retrofit自定义的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()); // 主线程Handler
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
在这个Android对象里,有一个主线程的Handler,用来post一个Runnable,在之后的构造中,它会被做为默认回调执行者(defaultCallbackExecutor)来被封装成默认调用工厂(defaultCallAdapterFactory),添加进adapterFactories这个列表中。
public Retrofit build() {
....
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> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
....
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
在执行我们接口中的方法时,会被用来构造CallAdapter(通过调用Callback.Factory里的get()方法),假设调用的是ExecutorCallAdapterFactory,那么这个CallAdapter的adapt()方法会返回一个ExecutorCallbackCall(故而我们在最外层调用接口里的方法,返回的就是ExecutorCallbackCall):
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
...
return new CallAdapter<Object, Call<?>>() {
...
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
参数中的Call默认是okHttpCall。而后这个okHttpCall会做为ExecutorCallbackCall的代理(delegate),等到我们调用ExecutorCallback的enqueue()方法,就会先执行okHttpCall的enqueue(),这里才会真正执行网络请求。
@Override public void enqueue(final Callback<T> callback) {
... // 判空
delegate.enqueue(new Callback(){...});
}
在okHttpCall.enqueue()里,会先构造一个RealCall(createRawCall()方法返回的是newRealCall())对象,执行RealCall的enqueue()方法
@Override public void enqueue(final Callback<T> callback) {
...// 判空
okhttp3.Call call;
....
call = rawCall = createRawCall();
....
call.enqueue(new okhttp3.Callback(){...});
}
createRawCall()方法:
private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
...
return call;
}
newCall()方法的实现
@Override public Call newCall(Request request) {
return new RealCall(this, request, false /* for web socket */);
}
RealCall的enqueue()方法又调用了Dispatcher的enqueue()方法,传入一个异步Call(AsyncCall)
@Override public void enqueue(Callback responseCallback) {
....
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
Dispatcher.enqueue():
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
当缓存到了一定数量前,利用线程池(executorService)执行我们的call,实际是执行AsyncCall的execute()方法(AsyncCall是RealCall的内部类):
@Override protected void execute() {
boolean signalledCallback = false;
try {
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException e) {
... //异常处理
}
}
调用了getResponseWithInterceptorChain()方法获取请求结果Response
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
这些处理我看不怎么懂,所以假设已经成功获取了Response,就会一路返回上层的Callback,直至返回到我们在ExecutorCallbackCall的enqueue()方法中,先执行delegate.enqueue()中的onResponse(),最后执行callbackExecutor.execute()方法
@Override public void enqueue(final Callback<T> callback) {
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() { // 执行这里的callbackExecutor.execute()
@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);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() { // 失败也是
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
这个callbackExecutor就是上面说的Android对象中的Executor(MainThreadExecutor),它的execute(),就是主线程handler去post一个runnable
static class Android extends Platform {
....
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) { // 最终的execute()
handler.post(r);
}
}
}
这个runnable,就是callbackExecutor.execute()方法中new出来的匿名内部类,来执行我们从最外面传进来的回调里的方法
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> 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); // 最终的回调
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
create()
retrofit.create()源代码如下:
public <T> T create(final Class<T> 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 {
....
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
在调用我们自己写的接口方法时,如果是在安卓平台,那么最主要的就是动态代理中最后几行代码。第二行new出来的okHttpCall说明了第一节中,我为什么说ExecutorCallAdapter.adapt()方法里的参数,默认是okHttpCall,而第三行adapt()方法,我也详细讲过了,所以我们这儿,只看第一行的loadServiceMethod()。
loadServiceMethod()方法,传进来的参数就是我们调用的接口方法对象
ServiceMethod<?, ?> loadServiceMethod(Method method) {
...
result = new ServiceMethod.Builder<>(this, method).build();
...
return result;
}
用了缓存技术,第一次使用则调用ServiceMethod.Builder的build()方法
public ServiceMethod build() {
callAdapter = createCallAdapter();
//结果转化,方法注解解析、参数注解解析等等
return new ServiceMethod<>(this);
}
除了运用我们构造时传进来的解析工厂进行对方法的解析外,最主要的是构造一个callAdapter,这时调用了createCallAdapter()方法
private CallAdapter<T, R> createCallAdapter() {
Type returnType = method.getGenericReturnType();
...
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
...
}
}
根据返回类型和注解获取,调用retrofit.callAdapter()方法:
public CallAdapter<?, ?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
...
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;
}
}
// 错误处理
}
一个参数一般是null,而后遍历所有设定的工厂,找到能解析的adapter,就返回(只要是接口中存在的方法,就不会出错)。至于get()方法怎么工作,在第一节我已然有所表述,这儿不再赘言。
结语
这里我们简单看了一下Retrofit2.0的源码,这里面用到的工厂模式,动态代理,线程池调用等知识,值得我们学习品味