内容简介:其中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使用及源码分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
PHP for the World Wide Web, Second Edition (Visual QuickStart Gu
Larry Ullman / Peachpit Press / 2004-02-02 / USD 29.99
So you know HTML, even JavaScript, but the idea of learning an actual programming language like PHP terrifies you? Well, stop quaking and get going with this easy task-based guide! Aimed at beginning ......一起来看看 《PHP for the World Wide Web, Second Edition (Visual QuickStart Gu》 这本书的介绍吧!