织梦手机网站怎么修改,wordpress配置字体,职业生涯规划大赛时间,高端网站制作报价Retrofit的基本使用流程很简洁#xff0c;但是简洁并不代表简单#xff0c;Retrofit为了实现这种简洁的使用流程#xff0c;内部使用了优秀的架构设计和大量的设计模式#xff0c;在我分析过Retrofit最新版的源码和大量优秀的Retrofit源码分析文章后#xff0c;我发现但是简洁并不代表简单Retrofit为了实现这种简洁的使用流程内部使用了优秀的架构设计和大量的设计模式在我分析过Retrofit最新版的源码和大量优秀的Retrofit源码分析文章后我发现要想真正理解Retrofit内部的核心源码流程和设计思想首先需要对这九大设计模式有一定的了解如下
1.Retrofit构建过程
建造者模式、工厂方法模式
2.创建网络请求接口实例过程
外观模式、代理模式、单例模式、策略模式、装饰模式建造者模式
3.生成并执行请求过程
适配器模式代理模式、装饰模式
复制代码
其次需要对OKHttp源码有一定的了解如果不了解的可以看看这篇Android主流三方库源码分析一、深入理解OKHttp源码。最后让我们按以上流程去深入Retrofit源码内部领悟它带给我们的设计之美。
二、Retrofit构建过程
1、Retrofit核心对象解析
首先Retrofit中有一个全局变量非常关键在V2.5之前的版本使用的是LinkedHashMap()它是一个网络请求配置对象是由网络请求接口中方法注解进行解析后得到的。
public final class Retrofit {
// 网络请求配置对象存储网络请求相关的配置如网络请求的方法、数据转换器、网络请求适配器、网络请求工厂、基地址等
private final MapMethod, ServiceMethod? serviceMethodCache new ConcurrentHashMap();
复制代码
Retrofit使用了建造者模式通过内部类Builder类建立一个Retrofit实例如下
public static final class Builder {
// 平台类型对象Platform - Android)
private final Platform platform;
// 网络请求工厂默认使用OkHttpCall工厂方法模式
private Nullable okhttp3.Call.Factory callFactory;
// 网络请求的url地址
private Nullable HttpUrl baseUrl;
// 数据转换器工厂的集合
private final ListConverter.Factory converterFactories new ArrayList();
// 网络请求适配器工厂的集合默认是ExecutorCallAdapterFactory
private final ListCallAdapter.Factory callAdapterFactories new ArrayList();
// 回调方法执行器在 Android 上默认是封装了 handler 的 MainThreadExecutor, 默认作用是切换线程子线程 - 主线程
private Nullable Executor callbackExecutor;
// 一个开关为true则会缓存创建的ServiceMethod
private boolean validateEagerly;
复制代码
2、Builder内部构造
下面看看Builder内部构造做了什么。
public static final class Builder {
…
Builder(Platform platform) {
this.platform platform;
}
public Builder() {
this(Platform.get());
}
…
}
class Platform {
private static final Platform PLATFORM findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
try {
// 使用JVM加载类的方式判断是否是Android平台
Class.forName(“android.os.Build”);
if (Build.VERSION.SDK_INT ! 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
// 同时支持Java平台
Class.forName(“java.util.Optional”);
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
static class Android extends Platform {
…
Override public Executor defaultCallbackExecutor() {
//切换线程子线程 - 主线程
return new MainThreadExecutor();
}
// 创建默认的网络请求适配器工厂如果是Android7.0或Java8上则使
// 用了并发包中的CompletableFuture保证了回调的同步
// 在Retrofit中提供了四种CallAdapterFactory(策略模式)
// ExecutorCallAdapterFactory默认、GuavaCallAdapterFactory、
// va8CallAdapterFactory、RxJavaCallAdapterFactory
Override List? extends CallAdapter.Factory defaultCallAdapterFactories(
Nullable Executor callbackExecutor) {
if (callbackExecutor null) throw new AssertionError();
ExecutorCallAdapterFactory executorFactory new ExecutorCallAdapterFactory(callbackExecutor);
return Build.VERSION.SDK_INT 24 ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory) singletonList(executorFactory); }
…
Override List? extends Converter.Factory defaultConverterFactories() {
return Build.VERSION.SDK_INT 24 ? singletonList(OptionalConverterFactory.INSTANCE) Collections.Converter.FactoryemptyList(); }
…
static class MainThreadExecutor implements Executor {
// 获取Android 主线程的Handler
private final Handler handler new Handler(Looper.getMainLooper());
Override public void execute(Runnable r) {
// 在UI线程对网络请求返回数据处理
handler.post®;
}
}
}
复制代码
可以看到在Builder内部构造时设置了默认Platform、callAdapterFactories和callbackExecutor。
3、添加baseUrl
很简单就是将String类型的url转换为OkHttp的HttpUrl过程如下
/** Set the API base URL. see #baseUrl(HttpUrl)
*/
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, “baseUrl null”);
return baseUrl(HttpUrl.get(baseUrl));
}
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, “baseUrl null”);
List pathSegments baseUrl.pathSegments();
if (!“”.equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException(baseUrl must end in /: baseUrl);
}
this.baseUrl baseUrl;
return this;
}
复制代码
4、添加GsonConverterFactory
首先看到GsonConverterFactory.creat()的源码。
public final class GsonConverterFactory extends Converter.Factory {
public static GsonConverterFactory create() {
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
if (gson null) throw new NullPointerException(“gson null”);
return new GsonConverterFactory(gson);
}
private final Gson gson;
// 创建了一个含有Gson对象实例的GsonConverterFactory
private GsonConverterFactory(Gson gson) {
this.gson gson;
}
复制代码
然后看看addConverterFactory()方法内部。
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, “factory null”));
return this;
}
复制代码
可知这一步是将一个含有Gson对象实例的GsonConverterFactory放入到了数据转换器工厂converterFactories里。
5、build过程
public Retrofit build() {
if (baseUrl null) {
throw new IllegalStateException(“Base URL required.”);
}
okhttp3.Call.Factory callFactory this.callFactory;
if (callFactory null) {
// 默认使用okhttp
callFactory new OkHttpClient();
}
Executor callbackExecutor this.callbackExecutor;
if (callbackExecutor null) {
// Android默认的callbackExecutor
callbackExecutor platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the defaultCall adapter.
ListCallAdapter.Factory callAdapterFactories new ArrayList(this.callAdapterFactories);
// 添加默认适配器工厂在集合尾部
callAdapterFactories.addAll(platform.defaultCallAdapterFactorisca llbackExecutor));
// Make a defensive copy of the converters.
ListConverter.Factory converterFactories new ArrayList(
1 this.converterFactories.size() platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters thatconsumeall types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories();
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
复制代码
可以看到最终我们在Builder类中看到的6大核心对象都已经配置到Retrofit对象中了。
三、创建网络请求接口实例过程
retrofit.create()使用了外观模式和代理模式创建了网络请求的接口实例我们分析下create方法。
public T create(final Class service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
// 判断是否需要提前缓存ServiceMethod对象
eagerlyValidateMethods(service);
}
// 使用动态代理拿到请求接口所有注解配置后创建网络请求接口实例
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) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
return loadServiceMethod(method).invoke(args ! null ? args : emptyArgs);
}
});
}
private void eagerlyValidateMethods(Class? service) {
Platform platform Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {
loadServiceMethod(method);
}
}
}
复制代码
继续看看loadServiceMethod的内部流程
ServiceMethod? loadServiceMethod(Method method) {
ServiceMethod? result serviceMethodCache.get(method);
if (result ! null) return result;
synchronized (serviceMethodCache) {
result serviceMethodCache.get(method);
if (result null) {
// 解析注解配置得到了ServiceMethod
result ServiceMethod.parseAnnotations(this, method);
// 可以看到最终加入到ConcurrentHashMap缓存中
serviceMethodCache.put(method, result);
}
}
return result;
}
abstract class ServiceMethod {
static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
// 通过RequestFactory解析注解配置工厂模式、内部使用了建造者模式
RequestFactory requestFactory RequestFactory.parseAnnotations(retrofit, method);
Type returnType method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method,
“Method return type must not include a type variable or wildcard: %s”, returnType);
}
if (returnType void.class) {
throw methodError(method, “Service methods cannot return void.”);
}
// 最终是通过HttpServiceMethod构建的请求方法
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract T invoke(Object[] args);
}
复制代码
以下为请求构造核心流程
根据RequestFactory#Builder构造方法和parseAnnotations方法的源码可知的它的作用就是用来解析注解配置的。
Builder(Retrofit retrofit, Method method) {
this.retrofit retrofit;
this.method method;
// 获取网络请求接口方法里的注释
this.methodAnnotations method.getAnnotations();
// 获取网络请求接口方法里的参数类型
this.parameterTypes method.getGenericParameterTypes();
// 获取网络请求接口方法里的注解内容
this.parameterAnnotationsArray method.getParameterAnnotations();
}
复制代码
接着看HttpServiceMethod.parseAnnotations()的内部流程。
static ResponseT, ReturnT HttpServiceMethodResponseT, ReturnT parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
//1.根据网络请求接口方法的返回值和注解类型
// 从Retrofit对象中获取对应的网络请求适配器
CallAdapterResponseT, ReturnT callAdapter createCallAdapter(retrofit,method);
// 得到响应类型
Type responseType callAdapter.responseType();
…
//2.根据网络请求接口方法的返回值和注解类型从Retrofit对象中获取对应的数据转换器
ConverterResponseBody, ResponseTresponseConverter
createResponseConverter(retrofit,method, responseType);
okhttp3.Call.Factory callFactory retrofit.callFactory;
return newHttpServiceMethod(requestFactory, callFactory, callAdapter,responseConverter);
}
复制代码
1.createCallAdapter(retrofit, method)
private static ResponseT, ReturnT CallAdapterResponseT, ReturnT createCallAdapter(
Retrofit retrofit, Method method) {
// 获取网络请求接口里方法的返回值类型
Type returnType method.getGenericReturnType();
// 获取网络请求接口接口里的注解
Annotation[] annotations method.getAnnotations();
try {
//noinspection unchecked
return (CallAdapterResponseT, ReturnT) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, “Unable to create call adapter for %s”, returnType);
}
}
public CallAdapter?, ? callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter?, ? nextCallAdapter(Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
…
int start callAdapterFactories.indexOf(skipPast) 1;
// 遍历 CallAdapter.Factory 集合寻找合适的工厂
for (int i start, count callAdapterFactories.size(); i count; i) {
CallAdapter?, ? adapter callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter ! null) {
return adapter;
}
}
}
复制代码
2.createResponseConverter(Retrofit retrofit, Method method, Type responseType)
private static ConverterResponseBody, ResponseT createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType,annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, “Unable to create converter for%s”, responseType);
}
}
public ConverterResponseBody, T responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public ConverterResponseBody, T nextResponseBodyConverter(
Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
…
int start converterFactories.indexOf(skipPast) 1;
// 遍历 Converter.Factory 集合并寻找合适的工厂, 这里是GsonResponseBodyConverter
for (int i start, count converterFactories.size(); i count; i) {
ConverterResponseBody, ? converter
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter ! null) {
//noinspection unchecked
return (ConverterResponseBody, T) converter;
}
}
复制代码
最终执行HttpServiceMethod的invoke方法
Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall(requestFactory, args, callFactory, responseConverter));
}
复制代码
最终在adapt中创建了一个ExecutorCallbackCall对象它是一个装饰者而在它内部真正去执行网络请求的还是OkHttpCall。
四、创建网络请求接口类实例并执行请求过程
1、service.listRepos()
1、CallList repos service.listRepos(“octocat”);
复制代码
service对象是动态代理对象Proxy.newProxyInstance()当调用getCall()时会被 它拦截然后调用自身的InvocationHandler#invoke()得到最终的Call对象。
2、同步执行流程 repos.execute()
Override public Response execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException(“Already executed.”);
executed true;
if (creationFailure ! null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
call rawCall;
if (call null) {
try {
// 创建一个OkHttp的Request对象请求
call rawCall createRawCall();
先自我介绍一下小编13年上海交大毕业曾经在小公司待过也去过华为、OPPO等大厂18年进入阿里一直到现在。
深知大多数初中级Android工程师想要提升技能往往是自己摸索成长或者是报班学习但对于培训机构动则近万的学费着实压力不小。自己不成体系的自学效果低效又漫长而且极易碰到天花板技术停滞不前
因此收集整理了一份《Android移动开发全套学习资料》送给大家初衷也很简单就是希望能够帮助到想自学提升又不知道该从何学起的朋友同时减轻大家的负担。 由于文件比较大这里只是将部分目录截图出来每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助可以扫码领取 总结
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识这里放上相关的我搜集整理的14套腾讯、字节跳动、阿里、百度等2021面试真题解析我把技术点整理成了视频和PDF实际上比预期多花了不少精力包知识脉络 诸多细节。 网上学习 Android的资料一大堆但如果学到的知识不成体系遇到问题时只是浅尝辄止不再深入研究那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。 《Android学习笔记总结移动架构视频大厂面试真题项目实战源码》点击传送门即可免费领取
大厂18年进入阿里一直到现在。**
深知大多数初中级Android工程师想要提升技能往往是自己摸索成长或者是报班学习但对于培训机构动则近万的学费着实压力不小。自己不成体系的自学效果低效又漫长而且极易碰到天花板技术停滞不前
因此收集整理了一份《Android移动开发全套学习资料》送给大家初衷也很简单就是希望能够帮助到想自学提升又不知道该从何学起的朋友同时减轻大家的负担。
[外链图片转存中…(img-eYkpWKkJ-1711224406974)]
[外链图片转存中…(img-dJbsA4LY-1711224406974)]
[外链图片转存中…(img-uwg20Aqt-1711224406975)]
[外链图片转存中…(img-jfBC5yID-1711224406975)]
由于文件比较大这里只是将部分目录截图出来每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助可以扫码领取 总结
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识这里放上相关的我搜集整理的14套腾讯、字节跳动、阿里、百度等2021面试真题解析我把技术点整理成了视频和PDF实际上比预期多花了不少精力包知识脉络 诸多细节。
[外链图片转存中…(img-7nne7k8n-1711224406975)] [外链图片转存中…(img-oyXIH8tG-1711224406975)]
[外链图片转存中…(img-Dz0a6umZ-1711224406976)]
[外链图片转存中…(img-70KvBCBT-1711224406976)] 网上学习 Android的资料一大堆但如果学到的知识不成体系遇到问题时只是浅尝辄止不再深入研究那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
[外链图片转存中…(img-MJztk78c-1711224406976)] 《Android学习笔记总结移动架构视频大厂面试真题项目实战源码》点击传送门即可免费领取