Retrofit 是如何工作的? 疑惑
调用接口的方法后是怎么发送请求的?
Retrofit 与 OkHttp 是怎么合作的?
Retrofit 中的数据究竟是怎么处理的?它是怎么返回 Rxjava.Observable 的?
基本使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public interface ApiService { @GET ("data/Android/" + GankConfig.PAGE_COUNT + "/{page}" ) Observable<GankResponse> getAndroid (@Path("page" ) int page) ; } Retrofit retrofit = new Retrofit.Builder() .baseUrl(baskUrl) .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create())) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(okHttpClient) .build(); ApiService service = retrofit.create(ApiService.class); Observable<GankResponse> observable = service.getAndroid(1 ); observable...
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 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> adapterFactories = new ArrayList<>(this .adapterFactories); adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); List<Converter.Factory> converterFactories = new ArrayList<>(this .converterFactories); return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly); }
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 25 26 27 28 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 (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.callAdapter.adapt(okHttpCall); } }); }
从上面的代码中可以看到,Retrofit 主要原理是利用了 Java 的动态代理 技术,把 ApiService 的方法调用集中到了InvocationHandler.invoke()
,再创建了 ServiceMethod,OkHttpCall,返回callAdapter.adapt
的结果。
ServiceMethod 的职责以及 loadServiceMethod 分析 ServiceMethod 是接口具体方法的抽象,它主要负责解析它对应的 method 的各个参数(它有各种如parseHeader()
的方法),比如注解@GET
,入参,另外还负责获取 callAdapter,responseConverter 等 Retrofit 配置,好为后面的 okhttp3.Request 做好参数准备,它的toRequest()
为 OkHttp 提供 Request,可以说它承载了后续 Http 请求所需的一切参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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; }
动态代理是有一定的性能损耗的,并且 ServiceMethod 的创建伴随着各种注解参数解析,这也是耗时间的,再加上一个 App 调用接口是非常频繁的,如果每次接口请求都需要重新生成那么有浪费资源损耗性能的可能,所以这里做了一份缓存来提高效率。
OkHttpCall OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
是在为 ServiceMethod 以及 args 生成了一个 OkHttpCall。从 OkHttpCall 这个名字可以猜到,它是对 OkHttp3.Call 的组合包装。(OkHttpCall 中有一个成员okhttp3.Call rawCall
)。
callAdapter.adapt()
流程分析最后return serviceMethod.callAdapter.adapt(okHttpCall);
这里涉及到的callAdapter
是由我们配置 Retrofit 时addCallAdapterFactory()
方法中传入的如RxJavaCallAdapterFactory.create()
生成,实例为RxJavaCallAdapterFactory
。
实例生成的大致流程:
ServiceMethod.Builder.build()
-> ServiceMethod.createCallAdapter()
-> retrofit.callAdapter()
-> adapterFactories
遍历 -> 最终到RxJavaCallAdapterFactory.get()#getCallAdapter()
-> return new SimpleCallAdapter(observableType, scheduler);
这里使用的是 RxJava,最终得到的是 callAdapter 为 SimpleCallAdapter,所以接下来分析SimpleCallAdapter#adapt()