介绍
网络请求库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 uncheckedreturn (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的源码,这里面用到的工厂模式,动态代理,线程池调用等知识,值得我们学习品味