题外话
第一次听说retrofit框架,还是同窗hanks推荐,SOHO的大字依旧发着光,hanks早已不在望京上班,hanks的github
Retrofit,一个类型安全的http客户端,适用于Android和Java
分析源码之前,首先在github上download源码 ,用IDEA打开编译。 先看一段官方提供的示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 //定义一个实体类 public static class Contributor { public final String login; public final int contributions; public Contributor(String login, int contributions) { this.login = login; this.contributions = contributions; } } //定义一个API接口 public interface GitHub { @GET("/repos/{owner}/{repo}/contributors") Call<List<Contributor>> contributors( @Path("owner") String owner, @Path("repo") String repo); } //创建retrofit对象 Retrofit retrofit = new Retrofit.Builder() .baseUrl(API_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); // 创建 GitHub 对象. GitHub github = retrofit.create(GitHub.class); //请求contributors方法 Call<List<Contributor>> call = github.contributors("square", "retrofit"); //得到结果 List<Contributor> contributors = call.execute().body(); //打印结果 for (Contributor contributor : contributors) { System.out.println(contributor.login + " (" + contributor.contributions + ")"); }
就这样,一个简单的Http请求就完成了,下面顺着流程,分析一下
Retrofit对象创建流程 Retrofit对象创建采用了Build模式,下面来看看Builder的源码
Retrofit.Builder 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 //成员变量和构造 public static final class Builder { //平台,主要有三个实现类 private Platform platform; //OkHttp包下面的接口,OkHttpClient就实现了它,这里主要是设置client private okhttp3.Call.Factory callFactory; //OkHttp包下的Url包装类 private HttpUrl baseUrl; //转换器工厂List,用户数据转对象,比如Gson,JackSon private List<Converter.Factory> converterFactories = new ArrayList<>(); //用来请求和接受的Call适配器,比如说可拓展RXJava private List<CallAdapter.Factory> adapterFactories = new ArrayList<>(); //callBack所在的线程,比如Android是在UI线程回调,这个默认在Platform的defaultCallbackExecutor方法提供 private Executor callbackExecutor; //是否预加载所以方法对应的ServiceMethod private boolean validateEagerly; Builder(Platform platform) { this.platform = platform; //converterFactories的默认有一个元素,为BuiltInConverters对象 converterFactories.add(new BuiltInConverters()); } //默认构造 public Builder() { this(Platform.get()); } }
再看build方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public Retrofit build() { //BaseUrl肯定不能为空 if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } //如果用户不设置callFactory,就在这里创建OkHttpClient对象,就在这里 okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory == null) { callFactory = new OkHttpClient(); } //如果用户不设置callbackExecutor,就取平台的callbackExecutor Executor callbackExecutor = this.callbackExecutor; if (callbackExecutor == null) { callbackExecutor = platform.defaultCallbackExecutor(); } //新建一个新数组,拷贝原数组数据并添加一个默认数据 List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories); adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); //同样是拷贝一份 List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories); //创建Retrofit对象 return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly); }
create方法解析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 //传入一个泛型Class,返回该泛型示例 public <T> T create(final Class<T> service) { //判断这个Class必须是接口,且不能有父接口 Utils.validateServiceInterface(service); //预加载当前service对象所有method对应的ServiceMethod 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 { //如果是一个Object默认的方法,由Object执行 if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } //如果是平台默认的方法,由该平台执行 if (platform.isDefaultMethod(method)) { return platform.invokeDefaultMethod(method, service, proxy, args); } //将method封装成ServiceMethod对象,loadServiceMethod设计有缓存 ServiceMethod serviceMethod = loadServiceMethod(method); //将serviceMethod和args封装成OkHttpCall对象 OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args); //由callAdapter对象的adapt方法执行okHttpCall,返回的就是接口申明的对象 return serviceMethod.callAdapter.adapt(okHttpCall); } }); } //刷新method缓存 private void eagerlyValidateMethods(Class<?> service) { Platform platform = Platform.get(); for (Method method : service.getDeclaredMethods()) { if (!platform.isDefaultMethod(method)) { loadServiceMethod(method); } } } //加载ServiceMethod ServiceMethod loadServiceMethod(Method method) { ServiceMethod result; //serviceMethodCacheRetrofit成员,用来缓存method ServiceMethod键值 synchronized (serviceMethodCache) { //去缓存 result = serviceMethodCache.get(method); //缓存没有,创建,存起来 if (result == null) { result = new ServiceMethod.Builder(this, method).build(); serviceMethodCache.put(method, result); } } return result; }
到了这里,Retrofit这个类的大致功能分析完了,梳理一下,Retrofit采用Build模式接受一堆配置参数构建,使用动态代理代理对象,这里发现几个比较关键的类,有 Platform,CallAdapter,Converter,ServiceMethod,OkHttpCall等 接下来,看来来这些类是怎么实现的
Platform标识当前运行环境所处的平台,有三个子类Java8、Android、IOS,这里只对Platform和Android这两个类源码作分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 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(); } //默认的回调Executor Executor defaultCallbackExecutor() { return null; } //默认CallAdapterFactory CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) { if (callbackExecutor != null) { return new ExecutorCallAdapterFactory(callbackExecutor); } return DefaultCallAdapterFactory.INSTANCE; } //是否是默认方法 boolean isDefaultMethod(Method method) { return false; } //执行默认方法,没有默认方法 Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable { throw new UnsupportedOperationException(); } //Android实现 static class Android extends Platform { //主线程回调 @Override public Executor defaultCallbackExecutor() { return new MainThreadExecutor(); } //默认CallAdapterFactory @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) { return new ExecutorCallAdapterFactory(callbackExecutor); } static class MainThreadExecutor implements Executor { //创建Handler对象,设置主线程Looper对象 private final Handler handler = new Handler(Looper.getMainLooper()); @Override public void execute(Runnable r) { //主线程执行任务 handler.post(r); } } } }
Platform类其实很简单,只做三件事,
判断当前处于何种环境,返回对应的Platform
创建回调Exector
创建defaultCallAdapterFactory
ServiceMethod类 ServiceMethod的创建是在loadServiceMethod方法中可以看到, 就是这句代码:new ServiceMethod.Builder(this, method).build(); 可以看出ServiceMethod也是Builder模式构造,我猜测ServiceMethod对应于method,是对method的封装,ServiceMethod类大多都是对注解进行 解析的,所以我打算拿到下一篇博客来讲。
Call接口 Call接口定义了一些同步,异步,取消,请求等方法,主要实现类是OkHttpCall OkHttpCall在newProxyInstance方法中可以看到:OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 final class OkHttpCall<T> implements Call<T> { //ServiceMethod对象 private final ServiceMethod<T> serviceMethod; //请求参数 private final Object[] args; //是否已经取消 private volatile boolean canceled; //构造方法 OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) { this.serviceMethod = serviceMethod; this.args = args; } //同步请求方法 @Override public Response<T> execute() throws IOException { //OkHttp包里的call okhttp3.Call call; synchronized (this) { //已经在执行,报异常 if (executed) throw new IllegalStateException("Already executed."); //标记为已执行 executed = true; //如果creationFailure不为空,报异常 if (creationFailure != null) { if (creationFailure instanceof IOException) { throw (IOException) creationFailure; } else { throw (RuntimeException) creationFailure; } } call = rawCall; if (call == null) { try { //创建OkHttp Call call = rawCall = createRawCall(); } catch (IOException | RuntimeException e) { creationFailure = e; throw e; } } } //取消请求 if (canceled) { call.cancel(); } //执行请求,并解析 return parseResponse(call.execute()); } //解析方法 Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException { //得到Body ResponseBody rawBody = rawResponse.body(); // Remove the body's source (the only stateful object) so we can pass the response along. rawResponse = rawResponse.newBuilder() .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength())) .build(); int code = rawResponse.code(); //错误回调 if (code < 200 || code >= 300) { try { // Buffer the entire body to avoid future I/O. ResponseBody bufferedBody = Utils.buffer(rawBody); return Response.error(bufferedBody, rawResponse); } finally { rawBody.close(); } } //TTP 204(no content)表示响应执行成功,但没有数据返回,浏览器不用刷新,不用导向新页面。 //HTTP 205(reset content) 表示响应执行成功,重置页面(Form表单),方便用户下次输入。 if (code == 204 || code == 205) { return Response.success(null, rawResponse); } ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody); try { //Json解析 T body = serviceMethod.toResponse(catchingBody); return Response.success(body, rawResponse); } catch (RuntimeException e) { // If the underlying source threw an exception, propagate that rather than indicating it was // a runtime exception. catchingBody.throwIfCaught(); throw e; } } }
OKHttpCall主要对OKHttp请求过程的封装,最终的Json解析也是在parseResponse方法中调用serviceMethod.toResponse方法执行;
CallAdapter接口和CallAdapter.Factory类 CallAdapter.Factory是为了生产CallAdapter示例而存在,源码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public interface CallAdapter<T> { //JSON解析后返回的格式,例如List<Contributor> Type responseType(); //输入参数R为JSON数据映射出的类型,例如List<Contributor>,返回参数T为最终的类型,例如Call<List<Contributor>> <R> T adapt(Call<R> call); //工厂 abstract class Factory { //创建CallAdapter对象,returnType为返回的格式比如Void或者Call<T> public abstract CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit); //根据数据参数获取其中第index个的type类型 protected static Type getParameterUpperBound(int index, ParameterizedType type) { return Utils.getParameterUpperBound(index, type); } //获取元素数据类型,将Type转换成Class protected static Class<?> getRawType(Type type) { return Utils.getRawType(type); } } }
从Platform的defaultCallAdapterFactory方法中看到两个CallAdapterFactory实现类ExecutorCallAdapterFactory和DefaultCallAdapterFactory,
DefaultCallAdapterFactory是一个单例,主要重写get方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 final class DefaultCallAdapterFactory extends CallAdapter.Factory { static final CallAdapter.Factory INSTANCE = new DefaultCallAdapterFactory(); @Override public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != Call.class) { return null; } //从returnType中得出responseType final Type responseType = Utils.getCallResponseType(returnType); //创建一个新的Adapter类 return new CallAdapter<Call<?>>() { @Override public Type responseType() { return responseType; } @Override public <R> Call<R> adapt(Call<R> call) { //直接返回,不做转换 return call; } }; } }
ExecutorCallAdapterFactory主要是采用静态代理的方式,处理CallBack的线程调度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 final class ExecutorCallAdapterFactory extends CallAdapter.Factory { //callbackExecutor final Executor callbackExecutor; ExecutorCallAdapterFactory(Executor callbackExecutor) { this.callbackExecutor = callbackExecutor; } @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); } }; } //代理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; } //代理enqueue方法 @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(); } } }
CallAdapter和factory的深入理解,放到下一篇,这一篇主要是把大概串通的,期待下一篇博客。