Retrofit源码简要分析
2016-08-04 11:39
316 查看
一、Retrofit的使用
本文使用的Retrofit 2.1.0版本。
在gradle中加入:
如果要是要解析json,还需加入:
如果要结合rxjava
需要加入:
Retrofit 2.1.0 依赖 okhttp 3发送网络请求。
所以Retrofit的源码其实并不多
http包下的是注解类。
接下来我们看看Retrofit是怎样创建的:
okHttpClient是okhttp3.0的okHttpClient,Retrofit将会使用它来发送网络请求。
当我们需要调用一个后台接口时,我们只需新建一个接口,然后根据请求类型以及参数写一个抽象方法
例如:
其中getTest方法就可以向后台发起一个请求,这个请求类型为Post 表单提交,参数名为test.
使用的话,可以这样:
得到 call 然后使用方法就和okhttp差不多了,可以使用call.enqueue()或call.execute()方法
他们分别代表了同步,和异步发起请求。
具体使用方法还请参考官网文档,这里就不再说了,接下来我们进入正题。
二、源码分析
我们在使用Retrofit的使用使用了这么 一段代码来创建retrofit
那么我们就先分析retrofit怎么被创建出来
这里使用了一个建造者模式,Build是Retrofit中的一个嵌套类
可以看到这个类中几个重要的域 Platform、okhttp3.Call.Factory、List< Converter.Factory >、List< CallAdapter.Factory > 、Executor
从类名上大致可以猜想到他们的作用,platform 代表目前使用的平台,可以是android、ios、java8
okhttp3.Call.Factory 的实现实际是我们传入的 okhttpClient,它的作用是发送网络请求
List
在Builder 的构造方法中可以看出它获取了当前的平台:
我们只看Android平台:
他有2个方法,一个是获得一个 CallAdapter.Factory ,它是一个制造CallAdapter的工厂
一个是获得一个Executor ,用来执行运行调用完成的结果。
接下来我们看,当我们调用了 retrofit.create(Api.class); 之后发生了什么
看以看到这个方法使用了java的动态代理,关于动态代理可以参考我的上一篇文章http://blog.csdn.net/a992036795/article/details/52101685
可以知道执行的将是invoke(Object proxy, Method method, Object… args) 这个方法,也就是执行:
如果我们传入参数正确的话,它将走最后这三行代码
我们就先看 ServiceMethod serviceMethod = loadServiceMethod(method); 这句代码的作用
serviceMethodCache 是一个Map,这里估计是考虑到了反射的效率问题,所以加了一个缓存机制,我们考到它使用new ServiceMethod.Builder(this, method).build(); 来创建一个
ServiceMethod这里又是一个建造者模式。我们点进去看一下
这里执行了一些方法,我们看些主要的:
先看第一个createCallAdapter
它调用了retrofit.callAdapter(returnType, annotations);
这里调用了 adapterFactories.get(i).get(returnType, annotations, this);
因为在Retrofit.Builder.build的时候 向adapterFactories 加入了我们ExecutorCallAdapterFactory,所以它最终调用的是这个类的get方法
可以看它的get方法,它返回了一个匿名类 CallAdapter< Call< ? > >
也就是说serviceMethod中的这个callAdapter 实际指向的就是这个匿名类
build中还有一个方法就是 parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
它最终解析了方法的注解,来获得请求的类型。
然后我们看retrofit.create的最后 2句
我们看到它创建出了一个OkHttpCall 然后调用serviceMethod.callAdapter.adapt 的adapter方法,并将okhttpCall传了进去,上文我们说到serviceMethod.callAdapter就是我们看的那个匿名类
这里看到 adapter 返回的是一个 ExecutorCallbackCall,我们看这里是一个装饰者模式
它将 OkHttpCall 装饰成了一个ExecutorCallbackCall 然后返回给了调用程序
实际他是将请求委托给了 OkHttpCall。然后我们来继续看OkHttpCall
它封装了okhttp 的call,最后请求实际是通过okhttp来进行了请求。
也即是说调用程序执行请求的过程是,拿到的实际是一个实现了retrofit2.Call< T > 接口的
ExecutorCallbackCall< T > 然后ExecutorCallbackCall 将请求转给 OkHttpCall
然后 OkHttpCall 调用 okhttp 发起请求
本文使用的Retrofit 2.1.0版本。
在gradle中加入:
compile 'com.squareup.retrofit2:retrofit:2.1.0'
如果要是要解析json,还需加入:
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
如果要结合rxjava
需要加入:
compile 'io.reactivex:rxjava:1.1.6' compile 'io.reactivex:rxandroid:1.2.1' compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
Retrofit 2.1.0 依赖 okhttp 3发送网络请求。
所以Retrofit的源码其实并不多
http包下的是注解类。
接下来我们看看Retrofit是怎样创建的:
new Retrofit.Builder() .baseUrl(Constants.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(okHttpClient) .build();
okHttpClient是okhttp3.0的okHttpClient,Retrofit将会使用它来发送网络请求。
当我们需要调用一个后台接口时,我们只需新建一个接口,然后根据请求类型以及参数写一个抽象方法
例如:
public interface Api { @FormUrlEncoded @POST("/api/test") Call<LoginResp> getTest(@Field("test")String test); }
其中getTest方法就可以向后台发起一个请求,这个请求类型为Post 表单提交,参数名为test.
使用的话,可以这样:
Api api = new Retrofit.Builder() .baseUrl("http://www.test.com/") .addConverterFactory(GsonConverterFactory.create()) .client(okHttpClient) .build() .create(Api.class); Call<LoginResp> call = api.getTest("test");
得到 call 然后使用方法就和okhttp差不多了,可以使用call.enqueue()或call.execute()方法
call.enqueue(new Callback<LoginResp>() { @Override public void onResponse(Call<LoginResp> call, retrofit2.Response<LoginResp> response) { } @Override public void onFailure(Call<LoginResp> call, Throwable t) { } }); //或者 try { call.execute(); } catch (IOException e) { e.printStackTrace(); }
他们分别代表了同步,和异步发起请求。
具体使用方法还请参考官网文档,这里就不再说了,接下来我们进入正题。
二、源码分析
我们在使用Retrofit的使用使用了这么 一段代码来创建retrofit
new Retrofit.Builder() .baseUrl(Constants.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(okHttpClient) .build()
那么我们就先分析retrofit怎么被创建出来
这里使用了一个建造者模式,Build是Retrofit中的一个嵌套类
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; // 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()); } public Builder() { this(Platform.get()); }
可以看到这个类中几个重要的域 Platform、okhttp3.Call.Factory、List< Converter.Factory >、List< CallAdapter.Factory > 、Executor
从类名上大致可以猜想到他们的作用,platform 代表目前使用的平台,可以是android、ios、java8
okhttp3.Call.Factory 的实现实际是我们传入的 okhttpClient,它的作用是发送网络请求
List
public Retrofit build() { if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory == null) { callFactory = new OkHttpClient(); } 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)); // Make a defensive copy of the converters. List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories); return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly); }
在Builder 的构造方法中可以看出它获取了当前的平台:
public Builder() { this(Platform.get()); }
class Platform { private static final Platform PLATFORM = findPlatform(); static Platform get() { return PLATFORM; } private static Platform findPlatform() { try { Class.forName("android.os.Build"); if (Build.VERSION.SDK_INT != 0) { return new Android(); } } catch (ClassNotFoundException ignored) { } try { Class.forName("java.util.Optional"); return new Java8(); } catch (ClassNotFoundException ignored) { } try { Class.forName("org.robovm.apple.foundation.NSObject"); return new IOS(); } catch (ClassNotFoundException ignored) { } return new Platform(); }
我们只看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); } } }
他有2个方法,一个是获得一个 CallAdapter.Factory ,它是一个制造CallAdapter的工厂
一个是获得一个Executor ,用来执行运行调用完成的结果。
接下来我们看,当我们调用了 retrofit.create(Api.class); 之后发生了什么
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() { 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. 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); } }); }
看以看到这个方法使用了java的动态代理,关于动态代理可以参考我的上一篇文章http://blog.csdn.net/a992036795/article/details/52101685
可以知道执行的将是invoke(Object proxy, Method method, Object… args) 这个方法,也就是执行:
// If the method is a method from Object then defer to normal invocation. 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);
如果我们传入参数正确的话,它将走最后这三行代码
我们就先看 ServiceMethod serviceMethod = loadServiceMethod(method); 这句代码的作用
ServiceMethod loadServiceMethod(Method method) { ServiceMethod result; synchronized (serviceMethodCache) { result = serviceMethodCache.get(method); if (result == null) { result = new ServiceMethod.Builder(this, method).build(); serviceMethodCache.put(method, result); } } return result; }
serviceMethodCache 是一个Map,这里估计是考虑到了反射的效率问题,所以加了一个缓存机制,我们考到它使用new ServiceMethod.Builder(this, method).build(); 来创建一个
ServiceMethod这里又是一个建造者模式。我们点进去看一下
public ServiceMethod build() { 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 = 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."); } 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); }
这里执行了一些方法,我们看些主要的:
先看第一个createCallAdapter
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."); } 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); } }
它调用了retrofit.callAdapter(returnType, annotations);
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++) { // 这里就调用了我们前文讲的那个 工厂ExecutorCallAdapterFactory,然后掉了它的get方法 CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this); if (adapter != null) { return adapter; } } StringBuilder builder = new StringBuilder("Could not locate call adapter for ") .append(returnType) .append(".\n"); if (skipPast != null) { builder.append(" Skipped:"); for (int i = 0; i < start; i++) { builder.append("\n * ").append(adapterFactories.get(i).getClass().getName()); } builder.append('\n'); } builder.append(" Tried:"); for (int i = start, count = adapterFactories.size(); i < count; i++) { builder.append("\n * ").append(adapterFactories.get(i).getClass().getName()); } throw new IllegalArgumentException(builder.toString()); }
这里调用了 adapterFactories.get(i).get(returnType, annotations, this);
因为在Retrofit.Builder.build的时候 向adapterFactories 加入了我们ExecutorCallAdapterFactory,所以它最终调用的是这个类的get方法
@Override public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != Call.class) { return null; } final Type responseType = Utils.getCallResponseType(returnType); return new CallAdapter<Call<?>>() { @Override public Type responseType() { return responseType; } @Override public <R> Call<R> adapt(Call<R> call) { return new ExecutorCallbackCall<>(callbackExecutor, call); } }; }
可以看它的get方法,它返回了一个匿名类 CallAdapter< Call< ? > >
也就是说serviceMethod中的这个callAdapter 实际指向的就是这个匿名类
build中还有一个方法就是 parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
它最终解析了方法的注解,来获得请求的类型。
然后我们看retrofit.create的最后 2句
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall);
我们看到它创建出了一个OkHttpCall 然后调用serviceMethod.callAdapter.adapt 的adapter方法,并将okhttpCall传了进去,上文我们说到serviceMethod.callAdapter就是我们看的那个匿名类
return new CallAdapter<Call<?>>() { @Override public Type responseType() { return responseType; } @Override public <R> Call<R> adapt(Call<R> call) { return new ExecutorCallbackCall<>(callbackExecutor, call); } }; } static final class ExecutorCallbackCall<T> implements Call<T> { final Executor callbackExecutor; final Call<T> delegate; ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) { this.callbackExecutor = callbackExecutor; this.delegate = delegate; } @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); } }); } }); } @Override public boolean isExecuted() { return delegate.isExecuted(); } @Override public Response<T> execute() throws IOException { return delegate.execute(); } @Override public void cancel() { delegate.cancel(); } @Override public boolean isCanceled() { return delegate.isCanceled(); } @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone. @Override public Call<T> clone() { return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone()); } @Override public Request request() { return delegate.request(); } }
这里看到 adapter 返回的是一个 ExecutorCallbackCall,我们看这里是一个装饰者模式
它将 OkHttpCall 装饰成了一个ExecutorCallbackCall 然后返回给了调用程序
实际他是将请求委托给了 OkHttpCall。然后我们来继续看OkHttpCall
final class OkHttpCall<T> implements Call<T> { private final ServiceMethod<T> serviceMethod; private final Object[] args; private volatile boolean canceled; // All guarded by this. private okhttp3.Call rawCall; private Throwable creationFailure; // Either a RuntimeException or IOException. private boolean executed; OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) { this.serviceMethod = serviceMethod; this.args = args; } @SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state. @Override public OkHttpCall<T> clone() { return new OkHttpCall<>(serviceMethod, args); } @Override public synchronized Request request() { okhttp3.Call call = rawCall; if (call != null) { return call.request(); } if (creationFailure != null) { if (creationFailure instanceof IOException) { throw new RuntimeException("Unable to create request.", creationFailure); } else { throw (RuntimeException) creationFailure; } } try { return (rawCall = createRawCall()).request(); } catch (RuntimeException e) { creationFailure = e; throw e; } catch (IOException e) { creationFailure = e; throw new RuntimeException("Unable to create request.", e); } } @Override public void enqueue(final Callback<T> callback) { if (callback == null) throw new NullPointerException("callback == null"); okhttp3.Call call; Throwable failure; synchronized (this) { if (executed) throw new IllegalStateException("Already executed."); executed = true; call = rawCall; failure = creationFailure; if (call == null && failure == null) { try { call = rawCall = createRawCall(); } catch (Throwable t) { failure = creationFailure = t; } } } if (failure != null) { callback.onFailure(this, failure); return; } if (canceled) { call.cancel(); } call.enqueue(new okhttp3.Callback() { @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) throws IOException { Response<T> response; try { response = parseResponse(rawResponse); } catch (Throwable e) { callFailure(e); return; } callSuccess(response); } @Override public void onFailure(okhttp3.Call call, IOException e) { try { callback.onFailure(OkHttpCall.this, e); } catch (Throwable t) { t.printStackTrace(); } } private void callFailure(Throwable e) { try { callback.onFailure(OkHttpCall.this, e); } catch (Throwable t) { t.printStackTrace(); } } private void callSuccess(Response<T> response) { try { callback.onResponse(OkHttpCall.this, response); } catch (Throwable t) { t.printStackTrace(); } } }); } @Override public synchronized boolean isExecuted() { return executed; } @Override public Response<T> execute() throws IOException { okhttp3.Call call; synchronized (this) { if (executed) throw new IllegalStateException("Already executed."); executed = true; if (creationFailure != null) { if (creationFailure instanceof IOException) { throw (IOException) creationFailure; } else { throw (RuntimeException) creationFailure; } } call = rawCall; if (call == null) { try { call = rawCall = createRawCall(); } catch (IOException | RuntimeException e) { creationFailure = e; throw e; } } } if (canceled) { call.cancel(); } return parseResponse(call.execute()); }
它封装了okhttp 的call,最后请求实际是通过okhttp来进行了请求。
也即是说调用程序执行请求的过程是,拿到的实际是一个实现了retrofit2.Call< T > 接口的
ExecutorCallbackCall< T > 然后ExecutorCallbackCall 将请求转给 OkHttpCall
然后 OkHttpCall 调用 okhttp 发起请求
相关文章推荐
- 【拆轮子系列】Retrofit 源码的简要分析
- U-boot源码简要分析(一)
- [Java] HashMap 源码简要分析
- Redis源码简要分析
- Redis源码简要分析
- Android Debuggerd 简要介绍和源码分析
- log4j源码简要分析 | 读取配置文件
- 【Java】Java集合框架源码和数据结构简要分析——List
- U-boot源码简要分析(二)
- 从源码角度简要分析ActionBar框架
- U-boot源码简要分析(二)
- poll系统调用源码简要分析
- mediawiki源码分析-入口Index.php简要分析
- 深入学习Django源码基础15 - views简要分析学习
- shttpd源码分析(2) 接口简要介绍
- 五、U-boot源码简要分析(一)
- 深入学习Django源码基础11 - 简要分析Django中template模块1
- Redis源码简要分析
- Redis源码简要分析