内容简介:其中ApiStore.class 是网络请求api,最终会通过层层解析,对应到ServiceManager类中在这个Retrofit 框架中最重要也是必须要理解的设计模式是动态代理模式,如果有同学不理解的,先去看一下动态代理设计模式。总而言之,就是apiStore.getHomeDetail()转为生成的动态代理类中去处理了。
retrofit = new Retrofit.Builder() .baseUrl("https://www.wanandroid.com") .addConverterFactory(GsonConverterFactory.create()) .client(httpClient.build()) .build(); ApiStores apiStore =retrofit.create(ApiStores.class); Call<HomeDetailJson> call = apiStore.getHomeDetail(); call.enqueue(new Callback<HomeDetailJson>() { @Override public void onResponse(Call<HomeDetailJson> call, Response<HomeDetailJson> response) { Log.d(TAG, "onResponse-->"); HomeDetailJson json = response.body(); } @Override public void onFailure(Call<HomeDetailJson> call, Throwable t) { Log.d(TAG, "onFailure-->" + t.toString()); } }); 复制代码
其中ApiStore.class 是网络请求api,最终会通过层层解析,对应到ServiceManager类中
public interface ApiStores { @GET("/article/list/0/json") Call<HomeDetailJson> getHomeDetail(); } 复制代码
在这个Retrofit 框架中最重要也是必须要理解的 设计模式 是动态代理模式,如果有同学不理解的,先去看一下动态代理设计模式。
总而言之,就是apiStore.getHomeDetail()转为生成的动态代理类中去处理了。
现在我们开始扒源码
- new Retrofit.Builder()
public Builder() { this(Platform.get()); } Builder(Platform platform) { this.platform = platform; } 复制代码
在new Builder的过程中,主要是找到了对应的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 平台下对应的Platform 就是Android()
-
baseUrl("www.wanandroid.com") 这段就不带着去看源码了,其实就是构造出okHttp 中使用的HttpUrl
-
addConverterFactory(GsonConverterFactory.create()) 数据解析使用
public Builder addConverterFactory(Converter.Factory factory) { converterFactories.add(checkNotNull(factory, "factory == null")); return this; } //一个判空检查 复制代码
GsonConverterFactory.create(),一个使用Gson 做数据解析的类
public static GsonConverterFactory create() { return create(new Gson()); } public static GsonConverterFactory create(Gson gson) { return new GsonConverterFactory(gson); } private final Gson gson; private GsonConverterFactory(Gson gson) { if (gson == null) throw new NullPointerException("gson == null"); this.gson = gson; } 复制代码
- client(httpClient.build())
public Builder callFactory(okhttp3.Call.Factory factory) { this.callFactory = checkNotNull(factory, "factory == null"); return this; } //指定了网络请求框架使用okHttp,其实Android 平台默认也是使用OKHttp 但是因为我要做网络log 日志打印,所以自己设置了一下 复制代码
- build() 这个方法主要是完成变量的赋值操作,我们挑一些重要的变量来看一下
public Retrofit build() { okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory == null) { callFactory = new OkHttpClient(); } //设置网络请求框架,默认是OkHttp Executor callbackExecutor = this.callbackExecutor; if (callbackExecutor == null) { callbackExecutor = platform.defaultCallbackExecutor(); } //回调执行器: MainThreadExecutor List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories); callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor)); //网络请求适配器,转换成不同平台试用的网络请求执行器:ExecutorCallAdapterFactory // Make a defensive copy of the converters. List<Converter.Factory> converterFactories = new ArrayList<>( 1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize()); //数据解析适配器 return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories), unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly); } 复制代码
- 重点来了,最重要的设计模式:代理模式。感觉这个是Retrofit 的灵魂,哇哈哈 retrofit.create(ApiStores.class);通过调用生成代理类,我们解析一下生成代理类的过程。
public <T> T create(final Class<T> service) { //我们直接看return方法,调用了Proxy.newProxyInstance()这个方法就是用来动态生成代理类, //此处推荐一篇动态代理的文章 https://blog.csdn.net/lovejj1994/article/details/78080124,相信大家看完这篇文章就知道newProxyInstance 到底做了什么,以及生成了一个什么样的动态代理类。 //最终的结果:Interface中对动态method 的调用都会走下面的invoke 方法。 //那么在代理的解析过程中都发生了什么呢? return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service }, new InvocationHandler() { private final Platform platform = Platform.get(); private final Object[] emptyArgs = new Object[0]; @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable { // If the method is a method from Object then defer to normal invocation. if (method.getDeclaringClass() == Object.class) {//object class 中定义的方法 return method.invoke(this, args); } if (platform.isDefaultMethod(method)) { return platform.invokeDefaultMethod(method, service, proxy, args); } //重点看下面这个方法 return loadServiceMethod(method).invoke(args != null ? args : emptyArgs); } }); } 复制代码
loadServiceMethod()有一个很重要的作用就是生成网络请求对象 ServiceManager
//做了优化,会根据Method 做缓存 private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>(); ServiceMethod<?> loadServiceMethod(Method method) { ServiceMethod<?> result = serviceMethodCache.get(method); //从缓存中获取对应的ServiceManager 对象 if (result != null) return result; synchronized (serviceMethodCache) { result = serviceMethodCache.get(method); if (result == null) { result = ServiceMethod.parseAnnotations(this, method); serviceMethodCache.put(method, result); } } return result; } 复制代码
从上面画的这个不规范的时序图可以看出,最终生成了HttpServiceMethod 这个类, 那invoke()方法也就调到对应的类中来看做了什么事情
@Override ReturnT invoke(Object[] args) { return callAdapter.adapt( new OkHttpCall<>(requestFactory, args, callFactory, responseConverter)); } 复制代码
callAdapter 从上面的时序图中,可以得出对应的实际类是ExecutorCallAdapterFactory 中通过get()方法new CallAdapter,那adapt()方法的调用也就是返回了ExecutorCallBackCall
- call.enqueue 也就是ExecutorCallBackCall.enqueue
@Override public void enqueue(final Callback<T> callback) { checkNotNull(callback, "callback == null"); //从上面的源码分析可得出delegate 对应的是OkHttpCall,所以下面的enqueue转向了OkHttp网络请求框架的逻辑,此处不再分析 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 2.5.0 源码分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 以太坊源码分析(36)ethdb源码分析
- [源码分析] kubelet源码分析(一)之 NewKubeletCommand
- libmodbus源码分析(3)从机(服务端)功能源码分析
- [源码分析] nfs-client-provisioner源码分析
- [源码分析] kubelet源码分析(三)之 Pod的创建
- Spring事务源码分析专题(一)JdbcTemplate使用及源码分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Kotlin实战
【美】Dmitry Jemerov(德米特里·詹莫瑞福)、【美】 Svetlana Isakova(斯维特拉娜·伊凡诺沃) / 覃宇、罗丽、李思阳、蒋扬海 / 电子工业出版社 / 2017-8 / 89.00
《Kotlin 实战》将从语言的基本特性开始,逐渐覆盖其更多的高级特性,尤其注重讲解如何将 Koltin 集成到已有 Java 工程实践及其背后的原理。本书分为两个部分。第一部分讲解如何开始使用 Kotlin 现有的库和API,包括基本语法、扩展函数和扩展属性、数据类和伴生对象、lambda 表达式,以及数据类型系统(着重讲解了可空性和集合的概念)。第二部分教你如何使用 Kotlin 构建自己的 ......一起来看看 《Kotlin实战》 这本书的介绍吧!