上一篇讲解了OKHttp,本篇来介绍下它的黄金搭档Retrofit,OKHttp+Retrofit是网络框架的不二之选。同是Square出品,和OKHttp融合起来非常简单。 Retofit是一个RESTful的HTTP网络请求框架,有以下特点:
基于OKHttp
通过注解配置网络请求参数
支持同步、异步请求
支持多种序列化、反序列化格式
解耦彻底、模块高度封装,使用很多设计模式来实现
基本使用 下面讲解的是官网的例子
创建网络请求接口 1 2 3 4 public interface GitHubService { @GET("users/{user}/repos") Call<List<Repo>> listRepos (@Path("user") String user) ; }
创建Retrofit实例(使用建造者模式) 1 2 3 4 Retrofit retrofit = new Retrofit .Builder() .baseUrl("https://api.github.com/" ) .addConverterFactory(GsonConverterFactory.create()) .build();
创建网络接口实例 1 2 3 GitHubService service = retrofit.create(GitHubService.class);Call<List<Repo>> repos = service.listRepos("yeungeek" );
发送网络请求 默认返回的是OKHttpCall,实际真正发送请求的就是OKHttp
同步 1 Response<List<Repo>> list = repos.execute()
异步 1 2 3 4 5 6 7 8 9 call.enqueue(new Callback <List<Repo>>() { @Override public void onResponse (Call<List<Repo>> call, Response<List<Repo>> response) { } @Override public void onFailure (Call<List<Repo>> call, Throwable t) { } });
请求流程 具体的请求流程可以分为7大步骤
解析网络请求接口的注解,配置网络请求参数
通过动态代理生成网络请求对象
通过CallAdapter,将网络请求对象进行平台适配(Android,Java8)
通过网络请求执行器(Call),发送网络请求
通过Converter进行数据解析
通过回调执行器,进行线程切换
在主线程处理返回结果
Refrofit最大特点是使用了大量的设计模式,来进行解耦,下图是完整的流程图(来自Stay 在 Retrofit分析-漂亮的解耦套路 ): 接下来通过源码分析,详细讲解上面的流程
源码分析 Retrofit初始化 1 2 3 4 5 6 Retrofit retrofit = new Retrofit .Builder() .baseUrl("https://api.github.com/" ) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build();
Retrofit声明 在使用Retrofit时,首先通过建造者模式构建Retrofit。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public final class Retrofit { private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap <>(); final okhttp3.Call.Factory callFactory; final HttpUrl baseUrl; final List<Converter.Factory> converterFactories; final List<CallAdapter.Factory> callAdapterFactories; final @Nullable Executor callbackExecutor; final boolean validateEagerly; Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl, List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories, @Nullable Executor callbackExecutor, boolean validateEagerly) { this .callFactory = callFactory; this .baseUrl = baseUrl; this .converterFactories = converterFactories; this .callAdapterFactories = callAdapterFactories; this .callbackExecutor = callbackExecutor; this .validateEagerly = validateEagerly; } ...... }
serviceMethodCache:网络请求配置对象缓存,通过解析网络请求接口后得到请求对象
callFactory:网络请求器工厂(Call),默认实现是OKHttp
baseUrl:网络请求Url地址
converterFactories:数据转换器工厂集合
callAdapterFactories:请求适配器工厂集合
callbackExecutor:回调方法执行器
validateEagerly:是否提前验证请求方法
剩下的步骤都是来初始化上面的参数
Builder 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public static final class Builder { private final Platform platform; private @Nullable okhttp3.Call.Factory callFactory; private HttpUrl baseUrl; private final List<Converter.Factory> converterFactories = new ArrayList <>(); private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList <>(); private @Nullable Executor callbackExecutor; private boolean validateEagerly; Builder(Platform platform) { this .platform = platform; } public Builder () { this (Platform.get()); } ...... }
Builder中的参数和 Retrfit 是意义一一对应的,默认构造函数进行平台的选择
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 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) { } return new Platform (); } ...... }
通过反射来判断选择Android还是Java8,以前版本还有对IOS平台的支持,最新版本已经去掉了。 我们看下Android平台:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 static class Android extends Platform { @Override public Executor defaultCallbackExecutor () { return new MainThreadExecutor (); } @Override CallAdapter.Factory defaultCallAdapterFactory (@Nullable Executor callbackExecutor) { if (callbackExecutor == null ) throw new AssertionError (); 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); } } }
baseUrl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public Builder baseUrl (String baseUrl) { checkNotNull(baseUrl, "baseUrl == null" ); HttpUrl httpUrl = HttpUrl.parse(baseUrl); if (httpUrl == null ) { throw new IllegalArgumentException ("Illegal URL: " + baseUrl); } return baseUrl(httpUrl); } ...... public Builder baseUrl (HttpUrl baseUrl) { checkNotNull(baseUrl, "baseUrl == null" ); List<String> pathSegments = baseUrl.pathSegments(); if (!"" .equals(pathSegments.get(pathSegments.size() - 1 ))) { throw new IllegalArgumentException ("baseUrl must end in /: " + baseUrl); } this .baseUrl = baseUrl; return this ; }
把String url 转换成HttpUrl,会对baseUrl进行合法性校验(URL参数是不是以”/“结尾)
ConverterFactory 1 2 3 4 public Builder addConverterFactory (Converter.Factory factory) { converterFactories.add(checkNotNull(factory, "factory == null" )); return this ; }
把factory加到数据转换器集合中,看下GsonFactory.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 public static GsonConverterFactory create (Gson gson) { if (gson == null ) throw new NullPointerException ("gson == null" ); return new GsonConverterFactory (gson); } private final Gson gson;private GsonConverterFactory (Gson gson) { this .gson = gson; } @Override public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); return new GsonResponseBodyConverter <>(gson, adapter); } @Override public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); return new GsonRequestBodyConverter <>(gson, adapter); }
GsonConverterFactory使用Gson 为初始化参数,实现responseBodyConverter
和requestBodyConverter
接口,进行真正的数据转换处理。
CallAdapterFactory 1 2 3 4 public Builder addCallAdapterFactory (CallAdapter.Factory factory) { callAdapterFactories.add(checkNotNull(factory, "factory == null" )); return this ; }
把factory加到请求适配器工厂集合中,Android 平台默认实现是ExecutorCallAdapterFactory,后面再进行详细讲解。
build 最后一步build生成Retrofit对象
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 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(); } List<CallAdapter.Factory> callAdapterFactories = new ArrayList <>(this .callAdapterFactories); callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); List<Converter.Factory> converterFactories = new ArrayList <>(1 + this .converterFactories.size()); converterFactories.add(new BuiltInConverters ()); converterFactories.addAll(this .converterFactories); return new Retrofit (callFactory, baseUrl, unmodifiableList(converterFactories), unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly); }
callFactory配置,默认OkHttpClient
callbackExecutor配置,Android 平台默认使用MainThreadExecutor
callAdapterFactories配置,先加入自定义的callAdapter,然后再加入defaultCallAdapterFactory
converterFactories配置,先加入内建转换器(BuiltInConverters),然后加入自定义的数据转换器
生成Retrofit对象
创建网络接口实例 1 2 3 4 5 6 7 8 public interface GitHubService { @GET("users/{user}/repos") Call<List<Repo>> listRepos (@Path("user") String user) ; } GitHubService service = retrofit.create(GitHubService.class);Call<List<Repo>> repos = service.listRepos("yeungeek" );
Retrofit通过外观模式和动态代理生成网络接口实例,网络接口的请求参数从接口声明获取
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 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, @Nullable Object[] args) throws Throwable { if (method.getDeclaringClass() == Object.class) { return method.invoke(this , args); } if (platform.isDefaultMethod(method)) { return platform.invokeDefaultMethod(method, service, proxy, args); } ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method); OkHttpCall<Object> okHttpCall = new OkHttpCall <>(serviceMethod, args); return serviceMethod.adapt(okHttpCall); } }); }
create方法中最重要的是使用了动态代理,调用接口的方法都会到Proxy的invoke方法中,在invoke方法中最重要的就是下面三行代码
1 2 3 4 ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method); OkHttpCall<Object> okHttpCall = new OkHttpCall <>(serviceMethod, args); return serviceMethod.adapt(okHttpCall);
loadServiceMethod 该方法读取网络请求接口里的方法,根据配置生成ServiceMethod对象
1 2 3 4 5 6 7 8 9 10 11 12 ServiceMethod<?, ?> loadServiceMethod(Method method) { ServiceMethod<?, ?> result = serviceMethodCache.get(method); if (result != null ) return result; synchronized (serviceMethodCache) { result = serviceMethodCache.get(method); if (result == null ) { result = new ServiceMethod .Builder<>(this , method).build(); serviceMethodCache.put(method, result); } } return result; }
loadServiceMethod会先从cache中获取对象,如果获取不到,则通过建造者模式生成ServiceMethod对象。
1 new ServiceMethod .Builder<>(this , method).build();
ServiceMethod 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 final class ServiceMethod <R, T> { static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*" ; static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}" ); static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM); private final okhttp3.Call.Factory callFactory; private final CallAdapter<R, T> callAdapter; private final HttpUrl baseUrl; private final Converter<ResponseBody, R> responseConverter; private final String httpMethod; private final String relativeUrl; private final Headers headers; private final MediaType contentType; private final boolean hasBody; private final boolean isFormEncoded; private final boolean isMultipart; private final ParameterHandler<?>[] parameterHandlers; ServiceMethod(Builder<R, T> builder) { this .callFactory = builder.retrofit.callFactory(); this .callAdapter = builder.callAdapter; this .baseUrl = builder.retrofit.baseUrl(); this .responseConverter = builder.responseConverter; this .httpMethod = builder.httpMethod; this .relativeUrl = builder.relativeUrl; this .headers = builder.headers; this .contentType = builder.contentType; this .hasBody = builder.hasBody; this .isFormEncoded = builder.isFormEncoded; this .isMultipart = builder.isMultipart; this .parameterHandlers = builder.parameterHandlers; } ...... }
callFactory:网络请求器工厂,和retrofit对象声明中的含义一样
callAdapter:网络请求适配器工厂
baseUrl:网络请求Url地址
responseConverter:Response 数据转换器
httpMethod:http 请求方法
relativeUrl:网络请求相对地址
headers:网络请求头
contentType:网络请求 body 类型
parameterHandlers:方法处理解析器
ServiceMethod.Builder 1 2 3 4 5 6 7 Builder(Retrofit retrofit, Method method) { this .retrofit = retrofit; this .method = method; this .methodAnnotations = method.getAnnotations(); this .parameterTypes = method.getGenericParameterTypes(); this .parameterAnnotationsArray = method.getParameterAnnotations(); }
methodAnnotations:网络请求接口方法注解
parameterTypes:网络请求接口方法里的参数注解
parameterAnnotationsArray:网络请求接口方法里的注解内容
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 30 31 32 33 34 35 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); } ..... 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); } ...... return new ServiceMethod <>(this ); }
createCallAdapter:根据接口方法返回类型、接口请求的注解,获取网络请求器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 private CallAdapter<T, R> 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 (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations); } catch (RuntimeException e) { throw methodError(e, "Unable to create call adapter for %s" , returnType); } }
createResponseConverter:根据接口请求注解类型、返回类型,获取数据数据转换器
1 2 3 4 5 6 7 8 9 10 private Converter<ResponseBody, T> createResponseConverter () { Annotation[] annotations = method.getAnnotations(); try { return retrofit.responseBodyConverter(responseType, annotations); } catch (RuntimeException e) { throw methodError(e, "Unable to create converter for %s" , responseType); } }
parseMethodAnnotation:解析请求接口的方法注解,主要有以下标签
Http请求方法
Headers
Multipart
FormUrlEncoded
parseParameter:对方法的参数注解进行解析 包含:Url,Path,Query,QueryName,QueryMap,Header,HeaderMap,Field,FieldMap,Part,PartMap,Body
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 private ParameterHandler<?> parseParameter( int p, Type parameterType, Annotation[] annotations) { ParameterHandler<?> result = null ; for (Annotation annotation : annotations) { ParameterHandler<?> annotationAction = parseParameterAnnotation( p, parameterType, annotations, annotation); if (annotationAction == null ) { continue ; } if (result != null ) { throw parameterError(p, "Multiple Retrofit annotations found, only one allowed." ); } result = annotationAction; } if (result == null ) { throw parameterError(p, "No Retrofit annotation found." ); } return result; }
OKHttpCall 根据serviceMethod和请求参数,创建OkHttpCall对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 final class OkHttpCall <T> implements Call <T> { private final ServiceMethod<T, ?> serviceMethod; private final @Nullable Object[] args; private volatile boolean canceled; @GuardedBy("this") private @Nullable okhttp3.Call rawCall; @GuardedBy("this") private @Nullable Throwable creationFailure; @GuardedBy("this") private boolean executed; OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) { this .serviceMethod = serviceMethod; this .args = args; } ...... }
serviceMethod和 args不做介绍了
rawCall:OKHttp,真正发送网络请求
canceled:取消请求标志位
executed:是否执行标志位
creationFailure:异常标志位
adapt 根据ServiceMethod的中的callAdapter,来真正执行adapt方法 ServiceMethod的adapt方法
1 2 3 T adapt (Call<R> call) { return callAdapter.adapt(call); }
Android 默认的返回 ExecutorCallAdapterFactory的Call 这里使用了静态代理delegate,加入一些额外的操作
1 2 3 4 5 6 7 8 public Call<Object> adapt (Call<Object> call) { return new ExecutorCallAdapterFactory .ExecutorCallbackCall(ExecutorCallAdapterFactory.this .callbackExecutor, call); } ...... ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) { this .callbackExecutor = callbackExecutor; this .delegate = delegate; }
RxJavaCallAdapterFactory返回的是Observable
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 @Override public Object adapt (Call<R> call) { Observable<Response<R>> responseObservable = isAsync ? new CallEnqueueObservable <>(call) : new CallExecuteObservable <>(call); Observable<?> observable; if (isResult) { observable = new ResultObservable <>(responseObservable); } else if (isBody) { observable = new BodyObservable <>(responseObservable); } else { observable = responseObservable; } if (scheduler != null ) { observable = observable.subscribeOn(scheduler); } if (isFlowable) { return observable.toFlowable(BackpressureStrategy.LATEST); } if (isSingle) { return observable.singleOrError(); } if (isMaybe) { return observable.singleElement(); } if (isCompletable) { return observable.ignoreElements(); } return observable; }
经过上面几步操作 Call<List<Repo>> repos = service.listRepos("yeungeek")
,返回了一个 OKHttpCall 对象。
发送网络请求 请求和 OKHttp 一样,分为同步请求和异步请求
同步请求 execute 首先会调用ExecutorCallbackCall的execute方法:
1 2 3 @Override public Response<T> execute () throws IOException { return delegate.execute(); }
delegate代理实际是 OKHttpCall,最终会调用OKHttpCall的execute方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Override public Response<T> execute () throws IOException { okhttp3.Call call; ...... call = rawCall; if (call == null ) { try { call = rawCall = createRawCall(); } catch (IOException | RuntimeException | Error e) { throwIfFatal(e); creationFailure = e; throw e; } } } if (canceled) { call.cancel(); } return parseResponse(call.execute()); }
createRawCall 创建真正发送的请求Request对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 private okhttp3.Call createRawCall () throws IOException { okhttp3.Call call = serviceMethod.toCall(args); if (call == null ) { throw new NullPointerException ("Call.Factory returned null." ); } return call; } okhttp3.Call toCall (@Nullable Object... args) throws IOException { RequestBuilder requestBuilder = new RequestBuilder (httpMethod, baseUrl, relativeUrl, headers, contentType, hasBody, isFormEncoded, isMultipart); @SuppressWarnings("unchecked") ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers; int argumentCount = args != null ? args.length : 0 ; if (argumentCount != handlers.length) { throw new IllegalArgumentException ("Argument count (" + argumentCount + ") doesn't match expected count (" + handlers.length + ")" ); } for (int p = 0 ; p < argumentCount; p++) { handlers[p].apply(requestBuilder, args[p]); } return callFactory.newCall(requestBuilder.build()); }
parseResponse 调用OKHttp的execute发送网络请求,根据网络请求结果再进行结果解析
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 Response<T> parseResponse (okhttp3.Response rawResponse) throws IOException { ResponseBody rawBody = rawResponse.body(); rawResponse = rawResponse.newBuilder() .body(new NoContentResponseBody (rawBody.contentType(), rawBody.contentLength())) .build(); int code = rawResponse.code(); if (code < 200 || code >= 300 ) { try { ResponseBody bufferedBody = Utils.buffer(rawBody); return Response.error(bufferedBody, rawResponse); } finally { rawBody.close(); } } if (code == 204 || code == 205 ) { rawBody.close(); return Response.success(null , rawResponse); } ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody (rawBody); try { T body = serviceMethod.toResponse(catchingBody); return Response.success(body, rawResponse); } catch (RuntimeException e) { catchingBody.throwIfCaught(); throw e; } }
先对响应码进行处理,再通过serviceMethod.toResponse选择数据转换器,对数据进行解析后,生成Response对象返回
异步请求 异步请求的流程和同步请求一样,就是再回调处理会进行线程切换 ExecutorCallbackCall的enqueue方法
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 @Override public void enqueue (final Callback<T> callback) { checkNotNull(callback, "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()) { 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切换到主线程 OKHttpCall的enqueue方法:
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 @Override public void enqueue (final Callback<T> callback) { checkNotNull(callback, "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) { throwIfFatal(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) { Response<T> response; try { response = parseResponse(rawResponse); } catch (Throwable e) { callFailure(e); return ; } try { callback.onResponse(OkHttpCall.this , response); } catch (Throwable t) { t.printStackTrace(); } } @Override public void onFailure (okhttp3.Call call, IOException e) { callFailure(e); } private void callFailure (Throwable e) { try { callback.onFailure(OkHttpCall.this , e); } catch (Throwable t) { t.printStackTrace(); } } }); }
如果使用到RxJava,在上一节已经提到, adapt会进行适配,RxJava2CallAdapter的adapt方法中有对RxJava转换,具体逻辑实现这边先不展开
1 2 3 Observable<Response<R>> responseObservable = isAsync ? new CallEnqueueObservable <>(call) : new CallExecuteObservable <>(call);
Retrofit中的HTTP实现 Retrofit真正请求网络,底层使用的是OKHttp,Refrofit主要负责网络请求接口的封装,看下源码中与HTTP相关的注解 这些注解都是在接口上的声明,主要是HTTP的请求方法和参数,具体可以参考Android网络编程-HTTP/HTTPS ,这里也不具体展开了
设计模式应用 我们再回顾下这张流程图:
构建者模式 这个模式运用的比较多,Retrofit的Builder,ServiceMethod的Builder等 设计模式可以参考建造者模式(Bulider模式)详解
工厂模式 在Retrofit 初始化,addCallAdapterFactory中的CallAdapter就是用工厂方法模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public interface CallAdapter <R, T> { Type responseType () ; T adapt (Call<R> call) ; abstract class Factory { public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit); protected static Type getParameterUpperBound (int index, ParameterizedType type) { return Utils.getParameterUpperBound(index, type); } protected static Class<?> getRawType(Type type) { return Utils.getRawType(type); } } }
实现Factory中抽象方法get,就会返回不同的 CallAdapter 对象 设计模式可以参考工厂方法模式(详解版)
外观模式(门面模式) Retrofit 就是一个典型的外观类,它屏蔽了所有的实现细节,提供给使用者方便的接口,统一调用创建接口实例和网络请求配置的方法 设计模式可以参考外观模式(Facade模式)详解
策略模式 主要应用CallAdapter类的adapt方法,在 Retrofit addCallAdapterFactory,对应 Factory 生成不同的CallAdapter,adapt就可以调用到不同实现 CallAdapter就是一个Strategy,Retrofit 对应上下文(Context) 设计模式可以参考策略模式(策略设计模式)详解
适配器模式 还是在CallAdapter得到应用,Retrofit可以适配Android,Java8,RxJava,guava等平台, 不同平台有不同的特性,addCallAdapterFactory可以生成不同的平台的CallAdapter,把不同平台的特性,统一在一个接口中 设计模式可以参考适配器模式(Adapter模式)详解
代理模式 Retrofit实例的create方法,使用了动态代理模式,网络请求接口,都会调用到Proxy.newProxyInstance
的 invoke 方法中
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 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, @Nullable Object[] args) throws Throwable { if (method.getDeclaringClass() == Object.class) { return method.invoke(this , args); } if (platform.isDefaultMethod(method)) { return platform.invokeDefaultMethod(method, service, proxy, args); } ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method); OkHttpCall<Object> okHttpCall = new OkHttpCall <>(serviceMethod, args); return serviceMethod.adapt(okHttpCall); } }); }
除了使用动态代理,Retrofit 还使用了静态代理模式,ExecutorCallbackCall的delegate,在发送请求和接收响应的过程中,增加了一些额外逻辑
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "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);
}
});
}
});
}
设计模式可以参考代理模式(代理设计模式)详解 Retrofit使用了大量的设计模式,上面只是在主流过程使用到的,其他设计模式的应用,大家可以继续深入源码去分析,总之,Refrofit框架是非常值得深入研究的框架
参考