介绍
网络请求库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()方法返回的是new RealCall())对象,执行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,实际是执行AysyncCall的execute()方法,真正调用的是RealCall的execute()方法:
@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的源码,这里面用到的工厂模式,动态代理,线程池调用等知识,值得我们学习品味