在上一篇okhttp源码解析(执行流程)的文章中,已经对okhttp
的基本执行流程作了一个较为详细的探究。本篇文章将对Android
开发中另外一个经常使用的网络请求框架Retrofit
作一个源码分析,有关Retrofit
的相关介绍在这里就不作赘述,咱们只对其执行过程以及其中涉及到的知识点进行相关分析。 html
在进行有关Retrofit
探究以前,须要知道两个知识点:注解和动态代理。之因此须要对这两个知识点有所准备,是由于它们在Retrofit
的源码中有所涉及,因此但愿你们可以有所理解。因为今天的重点是关Retrofit
,因此我针对这两个知识点为你们准备了几文章:java
Java注解深刻浅出
你真的彻底了解Java动态代理吗?看这篇就够了
Java动态代理
10分钟看懂动态代理设计模式
android
Retrofit
的请求注解的使用这里就再也不作详细介绍,这里为小伙伴本准备了一篇这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解),若是不熟悉的小伙伴,请提早看一下。json
使用以前须要添加如下依赖:设计模式
implementation 'com.squareup.retrofit2:retrofit:2.6.2' implementation 'com.squareup.retrofit2:converter-gson:2.6.2' 复制代码
关于后面两个依赖,下文会给出解释。数组
public class Bean { private int errorCode; private String errorMsg; private List<DataBean> data; public int getErrorCode() { return errorCode; } public void setErrorCode(int errorCode) { this.errorCode = errorCode; } public String getErrorMsg() { return errorMsg; } public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } public List<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { private int courseId; private int id; private String name; private int order; private int parentChapterId; private boolean userControlSetTop; private int visible; private List<?> children; public int getCourseId() { return courseId; } public void setCourseId(int courseId) { this.courseId = courseId; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getOrder() { return order; } public void setOrder(int order) { this.order = order; } public int getParentChapterId() { return parentChapterId; } public void setParentChapterId(int parentChapterId) { this.parentChapterId = parentChapterId; } public boolean isUserControlSetTop() { return userControlSetTop; } public void setUserControlSetTop(boolean userControlSetTop) { this.userControlSetTop = userControlSetTop; } public int getVisible() { return visible; } public void setVisible(int visible) { this.visible = visible; } public List<?> getChildren() { return children; } public void setChildren(List<?> children) { this.children = children; } @Override public String toString() { return "name:" + name; } } } 复制代码
为了接收到数据以后容易展现,重写了toString
方法。缓存
public interface ServiceApi { @GET("wxarticle/chapters/json") Call<Bean> getWxArtical(); } 复制代码
这里使用了鸿洋的wanandroid开放API,标示感谢。安全
这里为了表示的更清楚,因此在两个请求方法里面各建立了一个Retrofit
对象,在实际的开发中建立一个就好了。markdown
// 同步请求 public void execute() { Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://www.wanandroid.com") .addConverterFactory(GsonConverterFactory.create()) .build(); ServiceApi serviceApi = retrofit.create(ServiceApi.class); final Call<Bean> officialAccounts = serviceApi.getOfficialAccounts(); new Thread() { @Override public void run() { try { Response<Bean> response = officialAccounts.clone().execute(); for (int i = 0; i < response.body().getData().size(); i++) { Log.i("retrofit", "execute: " + response.body().getData().get(i).toString()); } } catch (IOException e) { e.printStackTrace(); } } }.start(); } 复制代码
// 异步请求 public void enqueue() { Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://www.wanandroid.com") .addConverterFactory(GsonConverterFactory.create()) .build(); ServiceApi serviceApi = retrofit.create(ServiceApi.class); Call<Bean> officialAccounts = serviceApi.getOfficialAccounts(); officialAccounts.clone().enqueue(new Callback<Bean>() { @Override public void onResponse(Call<Bean> call, Response<Bean> response) { for (int i = 0; i < response.body().getData().size(); i++) { Log.i("retrofit", "enqueue: " + response.body().getData().get(i).toString()); } } @Override public void onFailure(Call<Bean> call, Throwable t) { } }); } 复制代码
看一下请求结果: 网络
建立Retrofit
时,咱们调用了new Retrofit.Builder()
方法:
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; } ... public static final class Builder { //平台信息 private final Platform platform; //okhttp3请求工厂,默认是okhttp private @Nullable okhttp3.Call.Factory callFactory; //基础请求地址 private @Nullable 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; public Builder() { this(Platform.get()); } Builder(Platform platform) { this.platform = platform; } Builder(Retrofit retrofit) { platform = Platform.get(); callFactory = retrofit.callFactory; baseUrl = retrofit.baseUrl; // Do not add the default BuiltIntConverters and platform-aware converters added by build(). for (int i = 1, size = retrofit.converterFactories.size() - platform.defaultConverterFactoriesSize(); i < size; i++) { converterFactories.add(retrofit.converterFactories.get(i)); } // Do not add the default, platform-aware call adapters added by build(). for (int i = 0, size = retrofit.callAdapterFactories.size() - platform.defaultCallAdapterFactoriesSize(); i < size; i++) { callAdapterFactories.add(retrofit.callAdapterFactories.get(i)); } callbackExecutor = retrofit.callbackExecutor; validateEagerly = retrofit.validateEagerly; } public Builder baseUrl(String baseUrl) { //判断传入的baseUrl是否为null checkNotNull(baseUrl, "baseUrl == null"); return baseUrl(HttpUrl.get(baseUrl)); } public Builder baseUrl(HttpUrl baseUrl) { //再一次判断baseUrl是否为null checkNotNull(baseUrl, "baseUrl == null"); List<String> pathSegments = baseUrl.pathSegments(); // 判断baseUrl是否以'/'结尾,若是不是直接抛出异常 if (!"".equals(pathSegments.get(pathSegments.size() - 1))) { throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl); } this.baseUrl = baseUrl; return this; } public Builder addConverterFactory(Converter.Factory factory) { converterFactories.add(checkNotNull(factory, "factory == null")); return this; } ... 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.addAll(platform.defaultCallAdapterFactories(callbackExecutor)); List<Converter.Factory> converterFactories = new ArrayList<>( 1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize()); converterFactories.add(new BuiltInConverters()); converterFactories.addAll(this.converterFactories); converterFactories.addAll(platform.defaultConverterFactories()); return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories), unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly); } } } 复制代码
从上面的代码咱们能够看出,经过建立Retrofit.Builder
对象运用Builder
设计模式链式调用为Retrofit.Builder
中的属性进行赋值,调用build
方法时,将这些属性赋值给一个Retrofit
对象,最后将这个Retrofit
对象返回。咱们看一下这里面的属性都是什么意思。
在Retrofit类的内部会首先建立一个集合:
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>(); 复制代码
这个集合的Key
是一个Mehtod
对象,Value
是与Key
相对应的ServiceMethod
对象。ServiceMethod
对象是根据Method
解析以后得到,这里面包含了Method
的方法注解、参数注解等一些列属性。咱们从集合的名字就能看出来,这里面是将Method
和对应ServiceMethod
进行缓存的集合,这种方法咱们在EventBus
源码解析的时候就遇到过。这样作的目的就是为了加快运行速度,咱们在从此的开发中也能加以借鉴并运用。有关Method
和ServiceMethod
都会在下文中进行讲解,这里若是不知道是什么意思也不要紧。
这个对象是Retrofit.Builder
对象中进行定义的。
public static final class Builder { private final Platform platform; ... Builder(Retrofit retrofit) { platform = Platform.get(); } ... } class Platform { private static final Platform PLATFORM = findPlatform(); static Platform get() { return PLATFORM; } private static Platform findPlatform() { try { Class.forName("android.os.Build"); // 若是是Android平台 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(); } ... } 复制代码
在这里咱们能够看到这里会根据不一样的平台信息返回对应的Platform
对象,分别是Android
和Java8
,重点分析一下Android
。
static class Android extends Platform { // 一、判断方法是不是默认方法,所谓默认方法是指是不是Object类中已经定义的方法 // 若是是就返回true,不然返回false @IgnoreJRERequirement // Guarded by API check. @Override boolean isDefaultMethod(Method method) { if (Build.VERSION.SDK_INT < 24) { return false; } return method.isDefault(); } @Override public Executor defaultCallbackExecutor() { // 二、获取一个Executor对象,这个对象表明了回调执行器 return new MainThreadExecutor(); } // 三、得到Android版本下默认的网络适配器集合 @Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories( @Nullable Executor callbackExecutor) { if (callbackExecutor == null) throw new AssertionError(); // 默认的请求适配器 DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor); // 若是Android系统版本大于24,则会返回一个CompletableFutureCallAdapterFactory和DefaultCallAdapterFactory组成的集合。 // 不然返回只有DefaultCallAdapterFactory对象的集合 return Build.VERSION.SDK_INT >= 24 ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory) : singletonList(executorFactory); } @Override int defaultCallAdapterFactoriesSize() { return Build.VERSION.SDK_INT >= 24 ? 2 : 1; } // 四、获取Android版本下默认的转换器集合 @Override List<? extends Converter.Factory> defaultConverterFactories() { // 若是Android系统版本大于24,则会返回只有CompletableFutureCallAdapterFactory对象的集合 // 不然返回一个长度为0的集合 return Build.VERSION.SDK_INT >= 24 ? singletonList(OptionalConverterFactory.INSTANCE) : Collections.<Converter.Factory>emptyList(); } @Override int defaultConverterFactoriesSize() { return Build.VERSION.SDK_INT >= 24 ? 1 : 0; } // 2.1 这里返回的是Android主线程的回调 // 也就是说当网络请求完成后会回调到Android主线程中去,这也是Retrofit和OkHttp的不一样点之一 static class MainThreadExecutor implements Executor { private final Handler handler = new Handler(Looper.getMainLooper()); @Override public void execute(Runnable r) { handler.post(r); } } } 复制代码
在Android
平台里面咱们关注四点:
一、判断传入的
Method
对象是不是默认方法
二、获取执行回调器,这里默认的是将网络请求结果回调到Android
主线程中。
三、得到Android
版本下默认的网络适配器集合,这里会根据Android
版本号进行返回。
四、获取Android
版本下默认的转换器集合,它也是会根据Android
版本号进行返回。
这里有必要跟你们提早说一下,有关请求适配器(CallAdapter.Factory
)和转换器(Converter.Factory
)会在下面的文章中给出,这里先留一个印象。
咱们从单词的表面意思能够知道这个是请求工厂类,这个请求工厂类okhttp3
的Call
类型,这也说明了Retrofit
是基于okhttp
进行封装的。定义callFactory
对象咱们能够调用Retrofit.Builder.callFactory
方法进行设置,在Retrofit.Builder.build
方法中会将这个对象赋值个Retrofit
对象。
public final class Retrofit { ... public static final class Builder { private @Nullable okhttp3.Call.Factory callFactory; ... public Builder callFactory(okhttp3.Call.Factory factory) { this.callFactory = checkNotNull(factory, "factory == null"); return this; } ... public Retrofit build() { ... okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory == null) { callFactory = new OkHttpClient(); } ... } } ... } 复制代码
咱们能够看到当咱们没有调用Retrofit.Builder.callFactory
方法时,会给咱们默认设置一个OkHttpClient
对象。
baseUrl
做为请求的基础路径,它与咱们在HTTP API
接口中定义的方法注解中的相对路径组成了完整的请求路径。咱们能够调用Retrofit.Builder.baseUrl
方法进行设置,最后经过Retrofit.Builder.build
方法中会将这个对象赋值个Retrofit
对象。
public final class Retrofit { ... public static final class Builder { private @Nullable HttpUrl baseUrl; ... // 传入URL public Builder baseUrl(URL baseUrl) { checkNotNull(baseUrl, "baseUrl == null"); return baseUrl(HttpUrl.get(baseUrl.toString())); } // 传入String public Builder baseUrl(String baseUrl) { checkNotNull(baseUrl, "baseUrl == null"); return baseUrl(HttpUrl.get(baseUrl)); } public Builder baseUrl(HttpUrl baseUrl) { // 判空 checkNotNull(baseUrl, "baseUrl == null"); // 将url进行分割 List<String> pathSegments = baseUrl.pathSegments(); // 若是baseUrl不是以"/"结尾,抛出异常 if (!"".equals(pathSegments.get(pathSegments.size() - 1))) { throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl); } this.baseUrl = baseUrl; return this; } ... public Retrofit build() { ... // 再次判空 if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } ... // 传入Retrofit对象中 return new Retrofit(..., baseUrl, ..., ..., ..., ...); } } ... } 复制代码
设置的流程:
一、 能够调用两种方法,分别传入
URL
和String
。
二、 对baseUrl
进行判空,而后进行分割,若是是以"/"
结尾会抛出异常。
三、 再进行一次判空,最后赋值给Retrofit
对象。
converterFactories
集合内部存放的都是Converter.Factory
对象,咱们能够调用Retrofit.Builder.addConverterFactory
方法进行添加。
public final class Retrofit { ... public static final class Builder { private final List<Converter.Factory> converterFactories = new ArrayList<>(); ... public Builder addConverterFactory(Converter.Factory factory) { // 检查factory是否为null,而后加入到集合中 converterFactories.add(checkNotNull(factory, "factory == null")); return this; } ... public Retrofit build() { List<Converter.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 that consume all types. // 首先添加BuiltInConverters converterFactories.add(new BuiltInConverters()); // 而后添加调用addConverterFactory方法传入的Converter.Factory的集合 converterFactories.addAll(this.converterFactories); // 最后添加platform默认的Converter.Factory集合 converterFactories.addAll(platform.defaultConverterFactories()); // 根据converterFactories建立一个不可变集合传入 return new Retrofit(..., ..., unmodifiableList(converterFactories), ..., ..., ...); } } ... } 复制代码
Converter.Factory
从字面意思咱们能猜出它是和转换有关,具体的探究会放到下文中。
callAdapterFactories
集合中存放的是CallAdapter.Factory
对象,调用Retrofit.Builder.addCallAdapterFactory
方法来设置。
public final class Retrofit { ... public static final class Builder { private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(); ... public Builder addCallAdapterFactory(CallAdapter.Factory factory) { callAdapterFactories.add(checkNotNull(factory, "factory == null")); return this; } ... public Retrofit build() { List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories); // 这里不只添加了调用addCallAdapterFactory方法时设置的CallAdapter.Factory对象 // 同时还添加了platform中默认的CallAdapter.Factory对象 callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor)); // 根据callAdapterFactories建立一个不可变的集合传入 return new Retrofit(..., ..., ..., unmodifiableList(callAdapterFactories), ..., ...); } } ... } 复制代码
CallAdapter.Factory
从字面意思能够看出是请求适配器,有关于请求适配器是什么,也会放到下文中进行探究。
设置回调执行器咱们能够经过Retrofit.Builder.callbackExecutor
来设置,默认的会使用Platform
的回调执行器,也就是会将请求的执行结果回调到Android
主线程中。
public final class Retrofit { ... public static final class Builder { private @Nullable Executor callbackExecutor; ... public Builder callbackExecutor(Executor executor) { this.callbackExecutor = checkNotNull(executor, "executor == null"); return this; } ... public Retrofit build() { Executor callbackExecutor = this.callbackExecutor; if (callbackExecutor == null) { // 默认为platform中的回调执行器,会将请求结果回调到Android主线程 callbackExecutor = platform.defaultCallbackExecutor(); } return new Retrofit(..., ..., ..., ..., callbackExecutor, ...); } } ... } 复制代码
这个标识表示是否须要提早验证HTTP API
接口中的方法,咱们经过调用Retrofit.Builder.validateEagerly
方法进行设置,默认为false
。
public final class Retrofit { ... public static final class Builder { private boolean validateEagerly; ... public Builder validateEagerly(boolean validateEagerly) { this.validateEagerly = validateEagerly; return this; } ... public Retrofit build() { ... return new Retrofit(..., ..., ..., ..., ..., validateEagerly); } } ... } 复制代码
到这里咱们已经把Retrofit.Buidler
中的属性分析完了,可是咱们还遗留了两个问题:CallAdapter.Factory
和Converter.Factory
。这两个类究竟是作什么的?这里来看一下。
既然咱们已经知道这个类是用来进行请求适配的,那么咱们看一下里面是怎么运行的。
// 将响应类型为R的Call调整为T类型 public interface CallAdapter<R, T> { // 返回此适配器将HTTP响应正文转换为Java时使用的值类型对象。 // 例如, Call <Repo>的响应类型是Repo。 这个类型用于准备传递给adapt的call。 Type responseType(); // 这个方法是将Call<R>对象转成代理类T T adapt(Call<R> call); //CallAdapter工厂,retrofit默认的DefaultCallAdapterFactory其中不对Call作处理,是直接返回Call。 abstract class Factory { // 在这个方法中判断returnType是不是咱们支持的类型, // DefaultCallAdapterFactory没有作处理,由于在定义HTTP API接口中的方式时,returnType 即为Call<Requestbody> // RxJavaCallAdapterFactory 就是判断returnType是否是Observable<?> 类型 // 不支持时返回null // 返回值必须是Custom而且带有泛型(参数类型),根据HTTP API接口中的方法返回值,肯定returnType // 如: CustomCall<String> getCategories(),那肯定returnType就是CustomCall<String> public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit); // 用于获取泛型的参数 如 Call<Requestbody> 中 Requestbody protected static Type getParameterUpperBound(int index, ParameterizedType type) { return Utils.getParameterUpperBound(index, type); } // 用于获取泛型的原始类型 // 如Call<Requestbody>拿到的原始类型就是Call protected static Class<?> getRawType(Type type) { return Utils.getRawType(type); } } } 复制代码
看了这么多代码,可能仍是有点云里雾里,咱们找两个例子看一下。
final class DefaultCallAdapterFactory extends CallAdapter.Factory { @Override public @Nullable CallAdapter<?, ?> get( Type returnType, Annotation[] annotations, Retrofit retrofit) { // 若是返回值不是Call类型返回空 // 也就是说咱们在定义HTTP API接口中的方法时,返回值不是Call<?>类型的,将不会处理 if (getRawType(returnType) != Call.class) { return null; } return new CallAdapter<Object, Call<?>>() { @Override public Type responseType() { return ...; } @Override public Call<Object> adapt(Call<Object> call) { return ...; } }; } ... } 复制代码
咱们常常会看到Retrofit + RxJava
进行网络封装,若是要将Retrofit
和RxJava
结合到一块儿就须要RxJavaCallAdapterFactory
。
public final class RxJavaCallAdapterFactory extends CallAdapter.Factory { ... @Override public @Nullable CallAdapter<?, ?> get( Type returnType, Annotation[] annotations, Retrofit retrofit) { Class<?> rawType = getRawType(returnType); boolean isSingle = rawType == Single.class; boolean isCompletable = rawType == Completable.class; // 若是返回值不是Observable类型返回空 // 也就是说咱们在定义HTTP API接口中的方法时,返回值不是Observable<?>类型的,将不会处理 if (rawType != Observable.class && !isSingle && !isCompletable) { return null; } ... } } 复制代码
通过上面两个例子咱们应该对CallAdapter.Factory
有所了解了,这里来解释一下吧。
在咱们定义
HTTP API
接口时,里面方法的返回值须要由Retrofit
中添加的CallAdapter.Factory
决定,若是定义了CallAdapter.Factory
不支持的类型,请求将不会被执行。
从上面咱们也知道Converter.Factory
适用于转换的,咱们看下源码,看看它究竟是怎么转换的。
// 将F类型转成T类型 public interface Converter<F, T> { @Nullable T convert(F value) throws IOException; abstract class Factory { // 判断可否将API方法的返回类型从ResponseBody 转换为type // 若是不能直接返回null,反之返回对应的Converter.Factory对象 // type是由CallAdapter 接口里面的responseType()函数返回的。 public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { return null; } // 将API方法的输入参数类型从 type转换为requestBody // 用于转换被注解@Body, @Part 和 @PartMap标记的类型 public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { return null; } // 将API方法的输入参数类型从 type 转换为String // 用于转换被注解 @Header, @HeaderMap, @Path, @Query 和 @QueryMap 标记的类型 public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) { return null; } // 从type中提取index处泛型参数的上界 // 例如Map<String, ? extends Runnable>索引为1处返回Runnable protected static Type getParameterUpperBound(int index, ParameterizedType type) { return Utils.getParameterUpperBound(index, type); } // 从type中提取原始类类型 // 例如:List<? extends Runnable>返回的是List.class protected static Class<?> getRawType(Type type) { return Utils.getRawType(type); } } } 复制代码
看完以后仍是有点懵懵哒,咱们仍是找一个列子,还记的咱们调用Retrofit.Builder.addConverterFactory
传入的GsonConverterFactory
吗,看一下。
// 这个Converter.Factory类使用Gson来解析Json public final class GsonConverterFactory extends Converter.Factory { // 使用默认的Gson对象来建立GsonConverterFactory // 经过Gson将对象序列化或者反序列化成Json字符串 public static GsonConverterFactory create() { return create(new Gson()); } public static GsonConverterFactory create(Gson gson) { // 检查传入的gson对象是否为空 // 若是为空直接抛出异常 if (gson == null) throw new NullPointerException("gson == null"); return new GsonConverterFactory(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); } } // 将API方法的返回类型从ResponseBody 转换为type final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> { private final Gson gson; private final TypeAdapter<T> adapter; GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) { this.gson = gson; this.adapter = adapter; } @Override public T convert(ResponseBody value) throws IOException { JsonReader jsonReader = gson.newJsonReader(value.charStream()); try { T result = adapter.read(jsonReader); if (jsonReader.peek() != JsonToken.END_DOCUMENT) { throw new JsonIOException("JSON document was not fully consumed."); } return result; } finally { value.close(); } } } // 将API方法的输入参数类型从 type转换为requestBody final class GsonRequestBodyConverter<T> implements Converter<T, RequestBody> { private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8"); private static final Charset UTF_8 = Charset.forName("UTF-8"); private final Gson gson; private final TypeAdapter<T> adapter; GsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) { this.gson = gson; this.adapter = adapter; } @Override public RequestBody convert(T value) throws IOException { Buffer buffer = new Buffer(); Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8); JsonWriter jsonWriter = gson.newJsonWriter(writer); adapter.write(jsonWriter, value); jsonWriter.close(); return RequestBody.create(MEDIA_TYPE, buffer.readByteString()); } } 复制代码
从GsonRequestBodyConverter
的例子中咱们总结一下Converter.Factory
的做用:
Converter.Factory
是将HTTP API
方法中的参数在requestBody和responseBody
之间进行转换。
到这里咱们才算真正的把Retrofit.Buidler
中所涉及的属性和类分析完,休息一下,进行下半部分的分析。
public final class Retrofit { ... public <T> T create(final Class<T> service) { // 一、验证HTTP API接口 Utils.validateServiceInterface(service); if (validateEagerly) { // 二、验证HTTP API接口中的方法 eagerlyValidateMethods(service); } // 三、动态代理,整个Retrofit的核心之一 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 @Nullable 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); } return loadServiceMethod(method).invoke(args != null ? args : emptyArgs); } }); } ... } 复制代码
上面这段代码中有给出了三处注释,咱们逐个看一下
从注释1
中咱们得知这个方法是对咱们定义的HTTP API
接口进行验证,看一下它是怎么验证的。
final class Utils { ... static <T> void validateServiceInterface(Class<T> service) { if (!service.isInterface()) { throw new IllegalArgumentException("API declarations must be interfaces."); } if (service.getInterfaces().length > 0) { throw new IllegalArgumentException("API interfaces must not extend other interfaces."); } } ... } 复制代码
这里作了两步验证:
一、验证传入的对象是不是一个接口,若是不是直接抛出异常。
二、若是是一个接口,看看这个接口是不是继接口,若是继承了,也会抛出异常。
if (validateEagerly) { eagerlyValidateMethods(service); } 复制代码
这里是注释2
处的代码,validateEagerly
这个变量在以前的代码注释中已经给出了解释,它是对方法进行提早验证的标识,通常为false
,可是咱们仍是须要看一下这个方法中是怎么进行验证的。
private void eagerlyValidateMethods(Class<?> service) { Platform platform = Platform.get(); //得到接口中全部定义的方法,并遍历 for (Method method : service.getDeclaredMethods()) { // 一、判断是否若是是default方法,Android平台返回false // 二、判断方法是不是静态方法 if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) { // 若是符合条件,直接加载 loadServiceMethod(method); } } } 复制代码
在eagerlyValidateMethods
方法中也是作了两件事:
一、找出接口中的全部方法,看看是否符合条件。
二、若是符合条件,直接加载方法。
public final class Retrofit { //缓存集合,支持多线程访问、线程安全 //key:Method //value:Method对应的ServiceMethod private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>(); ... ServiceMethod<?> loadServiceMethod(Method method) { // 一、首先从方法缓存集合中获取 ServiceMethod<?> result = serviceMethodCache.get(method); // 二、若是有,直接返回 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; } } 复制代码
loadServiceMethod
这里作了三步事情:
一、根据传入的
Method
从缓存集合中获取对应的ServiceMethod
对象,若是有,直接返回;若是没有,对集合进行加锁,再次获取。这种方法将对象缓存起来的作法在分析EventBus
源码的时候就见过,目的就是为了提升效率。
二、若是上一步中没有获取到ServiceMethod
对象,将对Method
进行解析。
三、将Method
和它对应的ServiceMethod
对象存入到缓存集合中,返回结果。
abstract class ServiceMethod<T> { static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) { 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."); } return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); } abstract @Nullable T invoke(Object[] args); } 复制代码
注释2
处的验证HTTP API
接口中的方法咱们先分析到这里,上面这段代码咱们先不进行探究,由于很快咱们又会看到,具体流程会在接下来的分析中详细探究,但愿你们对这个方法有所印象。咱们先来总结一下注释2
处都是作了哪些事情:
一、获取到
HTTP API
接口中全部方法,遍历加载这些方法。
二、加载的过程当中先去缓存集合中看一下有没有与Method
对应的ServiceMethod
对象,若是有,直接返回;若是没有,对Method
进行解析,将解析结果封装成一个ServiceMethod
对象,并存入到缓存集合中,最后将ServiceMethod
返回。
public final class Retrofit { ... public <T> T create(final Class<T> service) { return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service }, new InvocationHandler() { // 一、这里返回的是Android平台 private final Platform platform = Platform.get(); // 二、建立一个Object数组,长度为0 private final Object[] emptyArgs = new Object[0]; @Override public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable { // 三、若是该方法是来自Object的方法,则听从正常调用。 if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } // 四、在Android平台始终返回false if (platform.isDefaultMethod(method)) { return platform.invokeDefaultMethod(method, service, proxy, args); } // 五、加载方法 return loadServiceMethod(method).invoke(args != null ? args : emptyArgs); } }); } ... } 复制代码
当调用retrofit.create(ServiceApi.class)
实际上会生成一个ServiceApi
的代理类对象。从前面的基础知识准备中咱们知道,当调用代理类对象中的方法时,最终会调用建立代理类对象所传入的第三个参数InvocationHandler.invoke
方法回调中去,在这个回调中对方法进行处理。retrofit.create(ServiceApi.class)
方法的主要流程已经在上面的代码注释中给出,这个方法最重要的一步是最后的加载方法,咱们来看一下。
ServiceMethod<?> loadServiceMethod(Method method) { ServiceMethod<?> result = serviceMethodCache.get(method); 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; } 复制代码
嗯哼?上面这段代码是否是很是熟悉?没错,在之提早验证方法的过程当中,咱们已经见到过这个方法,方法中的流程这里就再也不赘述,咱们继续往下看。
abstract class ServiceMethod<T> { static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) { // 一、根据传入的retrofit和method对象封装成RequestFactory // 这一步主要是进行解析注解 RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method); // 二、获取方法的returnType Type returnType = method.getGenericReturnType(); // 三、对方法的returnType进行验证 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."); } // 四、对方法的注解进行解析,并封装成一个ServiceMethod对象 // 这里返回的是HttpServiceMethod对象,他是ServiceMethod的子类 return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); } abstract @Nullable T invoke(Object[] args); } 复制代码
哎呦,这个方法咱们也见过,当时只是加深了一下印象,并无对其进行探究。这个方法中作了四步操做,它们对应的操做已经在上面代码的注释中给出。咱们重点来看一下第一步和第四步。
这个方法主要是根据传入的retrofit
对象和method
对象封装成RequestFactory
对象。
final class RequestFactory { static RequestFactory parseAnnotations(Retrofit retrofit, Method method) { return new Builder(retrofit, method).build(); } // method对象 private final Method method; // 基础url private final HttpUrl baseUrl; // 请求方法 final String httpMethod; // 相对url,它与基础url组成请求路径 private final @Nullable String relativeUrl; // 请求头 private final @Nullable Headers headers; // 表示具体请求中的媒体类型信息 private final @Nullable MediaType contentType; // 是否有请求体 private final boolean hasBody; // 是不是Form表单提交 private final boolean isFormEncoded; // 是否支持文件上传的Form表单 private final boolean isMultipart; // private final ParameterHandler<?>[] parameterHandlers; // 是不是kotlin挂起函数 final boolean isKotlinSuspendFunction; /** * Inspects the annotations on an interface method to construct a reusable service method. This * requires potentially-expensive reflection so it is best to build each service method only once * and reuse it. Builders cannot be reused. */ // 检查接口方法上的注释以构造可重用的服务方法。这须要潜在的昂贵反射,所以最好只构建一次每一个服务方法并重用它。 // 构建器不能重用。 static final class Builder { private static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*"; private static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}"); private static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM); // 传入的retrofit对象 final Retrofit retrofit; // 传入的method对象 final Method method; // method对象中的注解 final Annotation[] methodAnnotations; // method中参数注解数组 final Annotation[][] parameterAnnotationsArray; // method中参数类型数组 final Type[] parameterTypes; boolean gotField; boolean gotPart; boolean gotBody; boolean gotPath; boolean gotQuery; boolean gotQueryName; boolean gotQueryMap; boolean gotUrl; @Nullable String httpMethod; boolean hasBody; boolean isFormEncoded; boolean isMultipart; @Nullable String relativeUrl; @Nullable Headers headers; @Nullable MediaType contentType; @Nullable Set<String> relativeUrlParamNames; @Nullable ParameterHandler<?>[] parameterHandlers; boolean isKotlinSuspendFunction; Builder(Retrofit retrofit, Method method) { this.retrofit = retrofit; this.method = method; // 获取方法注解 this.methodAnnotations = method.getAnnotations(); // 获取方法参数类型 this.parameterTypes = method.getGenericParameterTypes(); // 获取方法注解数组 this.parameterAnnotationsArray = method.getParameterAnnotations(); } RequestFactory build() { // 遍历注解,对注解进行解析 for (Annotation annotation : methodAnnotations) { parseMethodAnnotation(annotation); } if (httpMethod == null) { throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.)."); } if (!hasBody) { if (isMultipart) { throw methodError(method, "Multipart can only be specified on HTTP methods with request body (e.g., @POST)."); } if (isFormEncoded) { throw methodError(method, "FormUrlEncoded can only be specified on HTTP methods with " + "request body (e.g., @POST)."); } } int parameterCount = parameterAnnotationsArray.length; parameterHandlers = new ParameterHandler<?>[parameterCount]; for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) { parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter); } if (relativeUrl == null && !gotUrl) { throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod); } if (!isFormEncoded && !isMultipart && !hasBody && gotBody) { throw methodError(method, "Non-body HTTP method cannot contain @Body."); } if (isFormEncoded && !gotField) { throw methodError(method, "Form-encoded method must contain at least one @Field."); } if (isMultipart && !gotPart) { throw methodError(method, "Multipart method must contain at least one @Part."); } // 返回一个RequestFactory对象 return new RequestFactory(this); } // 对注解进行解析 private void parseMethodAnnotation(Annotation annotation) { // 判断解析类型,根据注解的类型进行相应的解析 if (annotation instanceof DELETE) { parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false); } else if (annotation instanceof GET) { parseHttpMethodAndPath("GET", ((GET) annotation).value(), false); } else if (annotation instanceof HEAD) { parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false); } else if (annotation instanceof PATCH) { parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true); } else if (annotation instanceof POST) { parseHttpMethodAndPath("POST", ((POST) annotation).value(), true); } else if (annotation instanceof PUT) { parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true); } else if (annotation instanceof OPTIONS) { parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false); } else if (annotation instanceof HTTP) { HTTP http = (HTTP) annotation; parseHttpMethodAndPath(http.method(), http.path(), http.hasBody()); } else if (annotation instanceof retrofit2.http.Headers) { String[] headersToParse = ((retrofit2.http.Headers) annotation).value(); if (headersToParse.length == 0) { throw methodError(method, "@Headers annotation is empty."); } headers = parseHeaders(headersToParse); } else if (annotation instanceof Multipart) { if (isFormEncoded) { throw methodError(method, "Only one encoding annotation is allowed."); } isMultipart = true; } else if (annotation instanceof FormUrlEncoded) { if (isMultipart) { throw methodError(method, "Only one encoding annotation is allowed."); } isFormEncoded = true; } } //解析Http请求方法和路径 private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) { ... } // 解析请求头 private Headers parseHeaders(String[] headers) { ... } ... } ... } 复制代码
这里没有把RequestFactory
中全部的方法列出来,可是咱们从上面的代码和注释中咱们能够知道这个类都是作了哪些操做:
一、建立一个
RequestFactory.Builder
对象,同时传入Retrofit
对象和Method
对象。
二、建立完RequestFactory.Builder
对象以后,会对Method
对象的注解进行解析,解析的同时会对Buidler
对象进行初始化。
三、最后经过build
方法,建立一个RequestFactory
对象,并进行初始化。
在获得RequestFactory
对象以后,会调用HttpServiceMethod.parseAnnotations
方法,将获取的RequestFactory
传入,咱们看一下这里面都是作了什么操做。
/** Adapts an invocation of an interface method into an HTTP call. */ // 将接口方法的调用调整为HTTP请求 abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> { /** * Inspects the annotations on an interface method to construct a reusable service method that * speaks HTTP. This requires potentially-expensive reflection so it is best to build each service * method only once and reuse it. */ // 检查接口方法上的注释,以构造一个可重用的服务方法,该服务方法表示HTTP。 // 这须要潜在的昂贵反射,所以最好只构建一次每一个服务方法并重用它。 static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations( Retrofit retrofit, Method method, RequestFactory requestFactory) { boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction; boolean continuationWantsResponse = false; boolean continuationBodyNullable = false; // 得到全部方法上的全部注解 Annotation[] annotations = method.getAnnotations(); // 方法返回值类型 Type adapterType; // 是不是kotlin挂起函数 if (isKotlinSuspendFunction) { ... } else { // 获取方法返回类型 adapterType = method.getGenericReturnType(); } // 一、获取CallAdapter对象 // 根据以前的分析,这里得到的是DefaultCallAdapterFactory CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method, adapterType, annotations); // 校验返回类型是否正确 Type responseType = callAdapter.responseType(); // 返回类型不能为okhttp3.Response类型 if (responseType == okhttp3.Response.class) { throw methodError(method, "'" + getRawType(responseType).getName() + "' is not a valid response body type. Did you mean ResponseBody?"); } // 返回类型不能是Response,必需要包含泛型才行,相似于Response<String> if (responseType == Response.class) { throw methodError(method, "Response must include generic type (e.g., Response<String>)"); } // TODO support Unit for Kotlin? if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) { throw methodError(method, "HEAD method must use Void as response type."); } // 二、得到Converter对象 // 因为咱们设置了GsonConverterFactory,因此这里得到的是GsonConverterFactory对象 Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType); // 获取一个okhttp3.Call.Factory对象,其实就是一个OkHttpClient对象 okhttp3.Call.Factory callFactory = retrofit.callFactory; if (!isKotlinSuspendFunction) { return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter); } else if (continuationWantsResponse) { ... } else { ... } } private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter( Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) { try { // 四、从retrofit中根据returnType和annotations获取CallAdapter return (CallAdapter<ResponseT, 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); } } private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter( Retrofit retrofit, Method method, Type responseType) { Annotation[] annotations = method.getAnnotations(); try { // 五、从retrofit中根据responseType和annotations获取Converter 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 final class Retrofit { ... // 建立CallAdapter对象 public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) { // 调用nextCallAdapter传入skipPast、returnType、annotations // 注意:这里传入的skipPast为null return nextCallAdapter(null, returnType, annotations); } public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) { // 检查一下returnType和annotations是否为null checkNotNull(returnType, "returnType == null"); checkNotNull(annotations, "annotations == null"); // 这里找到callAdapterFactories集合的起始位置 // 因为skipPast为null因此得到的index为-1,而后加上1,起始位置仍是0 // 开始遍历集合 int start = callAdapterFactories.indexOf(skipPast) + 1; for (int i = start, count = callAdapterFactories.size(); i < count; i++) { // 咱们在分析CallAdapter.Factory时知道,调用get方法表示了, // 判断returnType是不是该CallAdapter.Factory支持的类型 // 若是不支持将会返回null // 反之会返回对应的CallAdapter.Factory // 因为没有额外设置,因此这里返回的是DefaultCallAdapterFactory CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this); // 若是有直接返回 if (adapter != null) { return adapter; } } // 到这里说明没有对应的CallAdapter.Factory // 拼接错误信息 StringBuilder builder = new StringBuilder("Could not locate call adapter for ") .append(returnType) .append(".\n"); if (skipPast != null) { builder.append(" Skipped:"); for (int i = 0; i < start; i++) { builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName()); } builder.append('\n'); } builder.append(" Tried:"); for (int i = start, count = callAdapterFactories.size(); i < count; i++) { builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName()); } // 抛出异常 throw new IllegalArgumentException(builder.toString()); } ... // 建立Converter对象 public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) { // 调用nextResponseBodyConverter传入skipPast、returnType、annotations // 注意:这里传入的skipPast为null return nextResponseBodyConverter(null, type, annotations); } public <T> Converter<ResponseBody, T> nextResponseBodyConverter( @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) { // 检查一下returnType和annotations是否为null checkNotNull(type, "type == null"); checkNotNull(annotations, "annotations == null"); // 这里找到converterFactories集合的起始位置 // 因为skipPast为null因此得到的index为-1,而后加上1,起始位置仍是0 // 开始遍历集合 int start = converterFactories.indexOf(skipPast) + 1; for (int i = start, count = converterFactories.size(); i < count; i++) { // 咱们在分析Converter.Factory时知道,调用responseBodyConverter方法表示了, // 判断可否将API方法的返回类型从ResponseBody 转换为type // 若是不能直接返回null, // 返回对应的Converter.Factory对象,咱们以前设置的是GsonConverterFactory,因此这里返回的是GsonConverterFactory Converter<ResponseBody, ?> converter = converterFactories.get(i).responseBodyConverter(type, annotations, this); if (converter != null) { // 若是有直接返回 return (Converter<ResponseBody, T>) converter; } } // 到这里说明没有对应的Converter.Factory // 拼接错误信息 StringBuilder builder = new StringBuilder("Could not locate ResponseBody converter for ") .append(type) .append(".\n"); if (skipPast != null) { builder.append(" Skipped:"); for (int i = 0; i < start; i++) { builder.append("\n * ").append(converterFactories.get(i).getClass().getName()); } builder.append('\n'); } builder.append(" Tried:"); for (int i = start, count = converterFactories.size(); i < count; i++) { builder.append("\n * ").append(converterFactories.get(i).getClass().getName()); } // 抛出异常 throw new IllegalArgumentException(builder.toString()); } ... } 复制代码
这里因为代码过长,因此咱们分步分析,在上面代码中有5处
比较重要的注释,首先看一下注释1
和注释2
,它们分别是用来获取CallAdapter.Factory
和Converter.Factory
,分别对应了注释4
和注释5
处。注释4
和注释5
都是从retrofit
对象中获取,具体的操做须要看上段代码的下半部分,最终获取的是DefaultCallAdapterFactory
和GsonConverterFactory
,具体流程已经在注释中给出。
咱们来看一下注释3
处的操做,下面是注释3
处的代码
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> { static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations( Retrofit retrofit, Method method, RequestFactory requestFactory) { boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction; ... // 获取一个okhttp3.Call.Factory对象,其实就是一个OkHttpClient对象 okhttp3.Call.Factory callFactory = retrofit.callFactory; if (!isKotlinSuspendFunction) { // 新建一个CallAdapted对象,传入requestFactory、callFactory、responseConverter、callAdapter // 最后返回出去 return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter); } else if (continuationWantsResponse) { ... } else { ... } } ... HttpServiceMethod(RequestFactory requestFactory, okhttp3.Call.Factory callFactory, Converter<ResponseBody, ResponseT> responseConverter) { this.requestFactory = requestFactory; this.callFactory = callFactory; this.responseConverter = responseConverter; } @Override final @Nullable ReturnT invoke(Object[] args) { Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter); // 这里首先找的是子类的adapt方法 // 由于建立的是CallAdapted,因此会调用CallAdapted的adapt放方法 return adapt(call, args); } protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args); // CallAdapted继承自HttpServiceMethod static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> { private final CallAdapter<ResponseT, ReturnT> callAdapter; // CallAdapted构造方法 CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory, Converter<ResponseBody, ResponseT> responseConverter, CallAdapter<ResponseT, ReturnT> callAdapter) { // 调用父类的构造方法,也就是HttpServiceMethod的构造方法 super(requestFactory, callFactory, responseConverter); this.callAdapter = callAdapter; } @Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) { // 返回callAdapter.adapt的结果 return callAdapter.adapt(call); } } ... } 复制代码
这里咱们须要把注释3
处的过程捋一捋,因为这个过程跟以前的分析联系比较紧密,因此会有点绕:
一、新建一个
CallAdapted
对象,传入requestFactory
、callFactory
、responseConverter
、callAdapter
。
二、建立CallAdapted
对象时调用其构造方法,因为它继承自HttpServiceMethod
,又调用了HttpServiceMethod
的构造方法,将参数传入。
三、咱们在以前的动态代理最后一步会调用return loadServiceMethod(method).invoke(...)
方法以后,又回调用HttpServiceMethod.adapt
方法。这个方法在HttpServiceMethod
中属于抽象方法,因此最终会调用其子类CallAdapted.adapt
方法。
四、在CallAdapted.adapt
的方法中会调用callAdapter.adapt
方法,在分析CallAdapte.Factory
时,咱们知道这个方法是将Call<R>
对象转成代理类T
。咱们没有设置CallAdapte.Factory
,因此使用的是DefaultCallAdapterFactory
,因此又调用了DefaultCallAdapterFactory
中的adapt
方法,并将OkHttpCall
传入了。
final class DefaultCallAdapterFactory extends CallAdapter.Factory { private final @Nullable Executor callbackExecutor; // 这个构造方法在Platform的Android子类中的defaultCallAdapterFactories方法中已经被调用。 DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) { //callbackExecutor为MainThreadExecutor,也就是说会将响应回调到Android主线程去 this.callbackExecutor = callbackExecutor; } // @Override public @Nullable CallAdapter<?, ?> get( Type returnType, Annotation[] annotations, Retrofit retrofit) { // 若是不是Call类型不予处理 if (getRawType(returnType) != Call.class) { return null; } if (!(returnType instanceof ParameterizedType)) { throw new IllegalArgumentException( "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>"); } final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType); // 查看注解是否包含SkipCallbackExecutor类型,咱们在使用时并无使用SkipCallbackExecutor的注解 // 因此这里的executor不为null final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class) ? null : callbackExecutor; return new CallAdapter<Object, Call<?>>() { @Override public Type responseType() { return responseType; } @Override public Call<Object> adapt(Call<Object> call) { // 判断executor是否为空,若是为空返回Call,这个call属于OkHttpCall // 若是不为空返回ExecutorCallbackCall return executor == null ? call : new ExecutorCallbackCall<>(executor, call); } }; } ... } 复制代码
static final class ExecutorCallbackCall<T> implements Call<T> { ... } 复制代码
因为这里与以前的分析联系比较紧密,有些绕,一不当心就会被绕进去,因此仍是分步分析。
一、在
Platform
的子类Android
中,已经建立了DefaultCallAdapterFactory
对象,而且传入了MainThreadExecutor
,这保证了响应会被回调到Android
主线程。
二、以前在获取CallAdapter
类型的时候,已经调用了DefaultCallAdapterFactory.get
方法,因此executor
对象不为空,而且返回了一个匿名的CallAdapter
对象。
三、在上面咱们调用DefaultCallAdapterFactory.adapt
方法时,就是调用了这个匿名对象的adapt
方法,这里返回的是ExecutorCallbackCall
对象。也就是说咱们在作网络请求时就是使用这个ExecutorCallbackCall
对象。
咱们在上面的分析中知道,实际上是ExecutorCallbackCall
对象进行网络请求,因此看一下它的源码。
同步请求的方法咱们也在以前的举例给出,咱们看一下源码
static final class ExecutorCallbackCall<T> implements Call<T> { final Executor callbackExecutor; final Call<T> delegate; // 构造方法传入callbackExecutor、Call ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) { // callbackExecutor属于MainThreadExecutor this.callbackExecutor = callbackExecutor; // delegate为OkHttpCall对象 this.delegate = delegate; } ... @Override public Response<T> execute() throws IOException { // delegate其实就是OkHttpCall对象 return delegate.execute(); } ... } 复制代码
final class OkHttpCall<T> implements Call<T> { @Override public Response<T> execute() throws IOException { okhttp3.Call call; synchronized (this) { ... call = rawCall; if (call == null) { try { // requestFactory根据args建立request对象 // 而后建立okhttp3.Call对象 call = rawCall = createRawCall(); } catch (IOException | RuntimeException | Error e) { throwIfFatal(e); // Do not assign a fatal error to creationFailure. creationFailure = e; throw e; } } } if (canceled) { call.cancel(); } // 使用okhttp3.Call对象进行请求,并将响应结果进行解析 return parseResponse(call.execute()); } private okhttp3.Call createRawCall() throws IOException { // requestFactory根据args建立request对象 // 而后根据request对象建立一个okhttp3.Call对象 okhttp3.Call call = callFactory.newCall(requestFactory.create(args)); if (call == null) { throw new NullPointerException("Call.Factory returned null."); } // 返回okhttp3.Call对象 return call; } // 对响应进行解析 Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException { // 响应体 ResponseBody rawBody = rawResponse.body(); // Remove the body's source (the only stateful object) so we can pass the response along. rawResponse = rawResponse.newBuilder() .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength())) .build(); // 得到响应码 int code = rawResponse.code(); // 根据响应码进行判断 if (code < 200 || code >= 300) { try { // Buffer the entire body to avoid future I/O. 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); } ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody); try { // 将响应体传入responseConverter对象也就是咱们以前设置的GsonConverterFactory中去 // 将响应体转成对应的Java对象 T body = responseConverter.convert(catchingBody); return Response.success(body, rawResponse); } catch (RuntimeException e) { // If the underlying source threw an exception, propagate that rather than indicating it was // a runtime exception. catchingBody.throwIfCaught(); throw e; } } } 复制代码
同步请求的过程:
一、
ExecutorCallbackCall
经过调用excute
方法,调用了传入的OkhttpCall
对象的excute
方法。
二、OkhttpCall
的excute
方法中,首先经过requestFactory
根据args
建立request
对象,而后建立okhttp3.Call
对象。
三、调用okhttp3.Call
的excute
方法,获取响应。
四、拿到响应后会根据响应码进行判断,经过判断后经过responseConverter
对象将响应体转成对应的Java
对象,并返回。
关于异步请求的使用,在咱们以前的举例中已经给出。
static final class ExecutorCallbackCall<T> implements Call<T> { // callbackExecutor属于MainThreadExecutor final Executor callbackExecutor; final Call<T> delegate; // 异步请求 @Override public void enqueue(final Callback<T> callback) { checkNotNull(callback, "callback == null"); // 根据同步请求咱们知道delegate就是一个OkhttpCall对象 // 调用OkhttpCall.exqueue方法执行异步请求 delegate.enqueue(new Callback<T>() { // 获取响应的回调 @Override public void onResponse(Call<T> call, final Response<T> response) { // 进行线程切换 // callbackExecutor就是MainThreadExecutor,其内部是经过主线程的Handler将Runnable发送到主线程去 // 从而达到切换线程的效果 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); } }); } }); } } 复制代码
final class OkHttpCall<T> implements Call<T> { // 异步请求方法 @Override public void enqueue(final Callback<T> callback) { checkNotNull(callback, "callback == null"); okhttp3.Call call; Throwable failure; synchronized (this) { ... call = rawCall; failure = creationFailure; if (call == null && failure == null) { try { // 建立Call对象 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) { throwIfFatal(e); callFailure(e); return; } try { // 请求成功的回调 callback.onResponse(OkHttpCall.this, response); } catch (Throwable t) { throwIfFatal(t); t.printStackTrace(); // TODO this is not great } } @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) { throwIfFatal(t); t.printStackTrace(); // TODO this is not great } } }); } private okhttp3.Call createRawCall() throws IOException { // requestFactory根据args建立一个request对象 // 将request对象分装成一个Call对象 okhttp3.Call call = callFactory.newCall(requestFactory.create(args)); if (call == null) { throw new NullPointerException("Call.Factory returned null."); } return call; } } 复制代码
异步请求中有一个重要的操做就是将请求结果经过主线程的Handle
发送到主线程去,从而达到线程切换的效果。
在源码分析的过程当中,咱们能发现Retrofit
中运用了大量的设置模式,这样作的好处就是将代码进行封装,方便咱们调用。这里面用到的设计模式包括:构建者模式
、单例模式
、工厂模式
、代理模式
、外观模式
、装饰模式
、策略模式
、适配器模式
。
因为在以前的文章中已经提到了构建者模式
、单例模式
、工厂模式
,因此这里再也不多作陈述,可是我会给出它们在Retrofit
中具体的出处。
一、构建者模式:最明显的就是在最初建立
Retrofit
对象时调用的new Retrofit.Builder().build()
。
二、单例模式:在Platform
类中获取Plathform
对象时使用的就是单例模式,有关单例的几种写法和它们之间的区别还但愿你们可以有所了解。
三、工厂模式:最明显的是CallAdapter.Factory
和Converter.Factory
,可是工厂模式中又有:简单工厂
、抽象工厂
和工厂方法
,须要区分开来。
说到代理模式,有静态代理和动态代理之分。在Retrofit
中咱们最初接触的是动态代理。
public final class Retrofit { ... public <T> T create(final Class<T> service) { Utils.validateServiceInterface(service); ... return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service }, new InvocationHandler() { ... @Override public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable { ... } }); } ... } 复制代码
这里只有动态代理,那Retrofit
中的静态代理在哪?在说静态代理以前要明白什么是静态代理:静态代理是指代理类在程序运行前已经存在的代理方式。
static final class ExecutorCallbackCall<T> implements Call<T> { ... // 这个delegate属于静态代理 final Call<T> 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()) { ... } else { ... } } }); } @Override public void onFailure(Call<T> call, final Throwable t) { ... } }); } } 复制代码
有关代理模式,在基础知识准备的时候已经给你们准备了几篇文章,这里就再也不一一列出了。
public interface ServiceApi { @GET("wxarticle/chapters/json") Call<Bean> getWxArtical(); } ServiceApi serviceApi = retrofit.create(ServiceApi.class); final Call<Bean> officialAccounts = serviceApi.getOfficialAccounts(); 复制代码
咱们在HTTP API
接口中定义了不少方法,参数都在方法上进行定义,只会告诉调用者须要传入哪些参数,具体的操做并不向外暴露,这个就是外观设计模式。这里为到家准备了一篇设计模式以外观模式。
容许向一个现有的对象添加新的功能,同时又不改变其结构。它是做为现有的类的一个包装。
static final class ExecutorCallbackCall<T> implements Call<T> { final Executor callbackExecutor; final Call<T> delegate; ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) { ... } @Override public void enqueue(final Callback<T> callback) { checkNotNull(callback, "callback == null"); delegate.enqueue(new Callback<T>() { ... }); } } 复制代码
咱们能够将ExecutorCallbackCall
看做是装饰类,但真正去执行请求的是OkHttpCall。之因此要有个装饰类,是但愿作一些额外操做。这里的操做就是线程转换,将子线程切换到主线程上去。有关装饰设计模式,为你们准备了两篇文章: 设计模式之死磕装饰器模式(原创)、 装饰者模式。
简单的来讲,策略模式就是作某些事情可能同时有多个方案,不一样的时期使用不一样的方案,怎样在调用的过程当中尽量的减小代码的修改,主要仍是使用了Java
中的多态。
public final class RxJava2CallAdapterFactory extends CallAdapter.Factory { @Override public @Nullable CallAdapter<?, ?> get( Type returnType, Annotation[] annotations, Retrofit retrofit) { Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType); Class<?> rawObservableType = getRawType(observableType); if (rawObservableType == Response.class) { ... } else if (rawObservableType == Result.class) { ... } else { ... } } ... } 复制代码
在RxJava2CallAdapterFactory
的get
方法中使用了策略模式,这里会根据rawObservableType
的类型,做出对应的操做,若是感兴趣的小伙伴能够到源码里面看一下。
有关策略模式这里为你们准备了一篇文章:LOL设计模式之「策略模式」。
咱们在看Retrofit
源码时,有可能在分析CallAdapter
时被搞的晕头转向。若是从适配器的概念上来说,就是将一个已经存在的东西,转成适合使用的东西。最多见的场景就是出国游玩的时候因为电源接口标准的不一样,咱们须要带一个转换头。
回头看Retrofit
,若是咱们一直时在Android
上使用,那就须要经过静态代理ExecutorCallbackCall
来切换线程,可是后来出现了新的技术Rxjava
,感受还挺好用的,不须要经过Handler
进行线程切换了。这时就须要转换一下,将将OkHttpCall
转换成rxjava(Scheduler)
的写法,大概就是这么一个套路。
关于适配器模式,也给你们准备了一篇文章:《JAVA与模式》之适配器模式
到这里咱们已经把Retrofit
的源码分析了一遍, 这里仍是建议你们本身跟着源码走一遍,毕竟纸上得来终觉浅。最后仍是那句话,本人是一名Android
小学生,文中若有不妥之处还望各位不吝赐教,本人将不胜感激。
这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)
Java注解深刻浅出
你真的彻底了解Java动态代理吗?看这篇就够了
Java动态代理
10分钟看懂动态代理设计模式
设计模式之死磕装饰器模式(原创)
LOL设计模式之「策略模式」
装饰者模式
《JAVA与模式》之适配器模式
wanandroid开放API