一 简单使用
引入依赖,
implementation 'com.squareup.okhttp3:okhttp:3.14.9'
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
implementation 'com.squareup.retrofit2:converter-gson:2.6.0'
implementation 'com.google.code.gson:gson:2.8.6'
复制代码
定义接口WanApi
,
interface WanApi {
//用注解标记网络请求类型get,参数path
@GET("article/list/{page}/json")
Call<WanArticleBean> articleList(@Path("page") int page);
}
复制代码
发起请求,
class RetrofitActivity extends AppCompatActivity {
final String SERVER = "https://www.xxx.com/";
@Override
protected void onCreate(Bundle savedInstanceState) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(SERVER) //指定服务器地址
.addConverterFactory(GsonConverterFactory.create()) //用gson将数据反序列化成实体
.build();
//运行期生成一个实现WanApi接口的类(字节码),并反射创建其实例
WanApi wanApi = retrofit.create(WanApi.class);
//得到Retrofit的call,他封装了okhttp的call
Call<WanArticleBean> call = wanApi.articleList(0);
//请求入队
call.enqueue(new Callback<WanArticleBean>() {
@Override
public void onResponse(Call<WanArticleBean> call, Response<WanArticleBean> response) {
//得到数据实体
WanArticleBean bean = response.body();
//不同于okhttp,Retrofit已经用Handler帮我们切回主线程了
mBinding.tvResult.setText("" + bean.getData().getDatas().size());
}
@Override
public void onFailure(Call<WanArticleBean> call, Throwable t) {}
});
}
}
二 实现原理
三 源码分析
创建Retrofit对象
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
对象返回。我们看一下这里面的属性都是什么意思。
serviceMethodCache集合
这个集合的Key
是一个Mehtod
对象,Value
是与Key
相对应的ServiceMethod
对象。ServiceMethod
对象是根据Method
解析之后获得,这里面包含了Method
的方法注解、参数注解等一些列属性。我们从集合的名字就能看出来,这里面是将Method
和对应ServiceMethod
进行缓存的集合,这种方法我们在EventBus
源码解析的时候就遇到过。这样做的目的就是为了加快运行速度,我们在今后的开发中也能加以借鉴并运用。有关Method
和ServiceMethod
都会在下文中进行讲解,这里如果不知道是什么意思也没关系。
Platform平台信息
这个对象是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 {
// 1、判断方法是否是默认方法,所谓默认方法是指是否是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() {
// 2、获取一个Executor对象,这个对象代表了回调执行器
return new MainThreadExecutor();
}
// 3、获得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;
}
// 4、获取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);
}
}
}
1、判断传入的Method
对象是否是默认方法
2、获取执行回调器,这里默认的是将网络请求结果回调到Android
主线程中。
3、获得Android
版本下默认的网络适配器集合,这里会根据Android
版本号进行返回。
4、获取Android
版本下默认的转换器集合,它也是会根据Android
版本号进行返回。
callFactory对象
我们从单词的表面意思可以知道这个是请求工厂类,这个请求工厂类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
对象
converterFactories转换器集合
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),
..., ..., ...);
}
}
...
}
callAdapterFactories请求适配器集合
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
从字面意思可以看出是请求适配器,有关于请求适配器是什么,也会放到下文中进行探究。
callbackExecutor回调执行器
设置回调执行器我们可以通过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, ...);
}
}
...
}
复制代码
validateEagerly提前验证方法标识
这个标识表示是否需要提前验证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
。这两个类到底是做什么的?这里来看一下。
CallAdapter.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
有所了解了,这里来解释一下吧。
Converter.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
的作用:
调用Retrofit.create方法
public final class Retrofit {
...
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
// 1 验证HTTP API接口中的方法
eagerlyValidateMethods(service);
}
// 2 动态代理,整个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:eagerlyValidateMethods(Class<?> service)
if (validateEagerly) {
eagerlyValidateMethods(service);
}
这里是注释2
处的代码,validateEagerly
这个变量在之前的代码注释中已经给出了解释,它是对方法进行提前验证的标识,一般为false
,但是我们还是需要看一下这个方法中是怎么进行验证的。
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
//获得接口中所有定义的方法,并遍历
for (Method method : service.getDeclaredMethods()) {
// 1、判断是否如果是default方法,Android平台返回false
// 2、判断方法是否是静态方法
if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
// 如果符合条件,直接加载
loadServiceMethod(method);
}
}
}
复制代码
在eagerlyValidateMethods
方法中也是做了两件事:
1、找出接口中的所有方法,看看是否符合条件。
2、如果符合条件,直接加载方法。
public final class Retrofit {
//缓存集合,支持多线程访问、线程安全
//key:Method
//value:Method对应的ServiceMethod
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
...
ServiceMethod<?> loadServiceMethod(Method method) {
// 1、首先从方法缓存集合中获取
ServiceMethod<?> result = serviceMethodCache.get(method);
// 2、如果有,直接返回
if (result != null) return result;
synchronized (serviceMethodCache) {
// 3、在再次确认缓存中的是否有方法
result = serviceMethodCache.get(method);
if (result == null) {
// 4、对方法的注解进行解析
result = ServiceMethod.parseAnnotations(this, method);
// 5、将方法传到方法缓存集合中
serviceMethodCache.put(method, result);
}
}
return result;
}
}
loadServiceMethod
这里做了三步事情:
1、根据传入的Method
从缓存集合中获取对应的ServiceMethod
对象,如果有,直接返回;如果没有,对集合进行加锁,再次获取。这种方法将对象缓存起来的做法在分析EventBus
源码的时候就见过,目的就是为了提高效率。
2、如果上一步中没有获取到ServiceMethod
对象,将对Method
进行解析。
3、将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: 动态代理
public final class Retrofit {
...
public <T> T create(final Class<T> service) {
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
// 1、这里返回的是Android平台
private final Platform platform = Platform.get();
// 2、创建一个Object数组,长度为0
private final Object[] emptyArgs = new Object[0];
@Override public @Nullable Object invoke(Object proxy, Method method,
@Nullable Object[] args) throws Throwable {
// 3、如果该方法是来自Object的方法,则遵从正常调用。
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// 4、在Android平台始终返回false
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 5、加载方法
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) {
// 1、根据传入的retrofit和method对象封装成RequestFactory
// 这一步主要是进行解析注解
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
// 2、获取方法的returnType
Type returnType = method.getGenericReturnType();
// 3、对方法的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.");
}
// 4、对方法的注解进行解析,并封装成一个ServiceMethod对象
// 这里返回的是HttpServiceMethod对象,他是ServiceMethod的子类
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
这个方法我们也见过,当时只是加深了一下印象,并没有对其进行探究。这个方法中做了四步操作,它们对应的操作已经在上面代码的注释中给出。我们重点来看一下第一步和第四步。
RequestFactory.parseAnnotations(retrofit, method)
这个方法主要是根据传入的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) {
...
}
...
}
...
}
1、创建一个RequestFactory.Builder
对象,同时传入Retrofit
对象和Method
对象。
2、创建完RequestFactory.Builder
对象之后,会对Method
对象的注解进行解析,解析的同时会对Buidler
对象进行初始化。
3、最后通过build
方法,创建一个RequestFactory
对象,并进行初始化
HttpServiceMethod.parseAnnotations(retrofit, method, 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();
}
// 1、获取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.");
}
// 2、获得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 {
// 4、从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 {
// 5、从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
处的过程捋一捋,由于这个过程跟之前的分析联系比较紧密,所以会有点绕:
1、新建一个CallAdapted
对象,传入requestFactory
、callFactory
、responseConverter
、callAdapter
。
2、创建CallAdapted
对象时调用其构造方法,由于它继承自HttpServiceMethod
,又调用了HttpServiceMethod
的构造方法,将参数传入。
3、我们在之前的动态代理最后一步会调用return loadServiceMethod(method).invoke(...)
方法之后,又回调用HttpServiceMethod.adapt
方法。这个方法在HttpServiceMethod
中属于抽象方法,所以最终会调用其子类CallAdapted.adapt
方法。
4、在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> {
...
}
1、在Platform
的子类Android
中,已经创建了DefaultCallAdapterFactory
对象,并且传入了MainThreadExecutor
,这保证了响应会被回调到Android
主线程。
2、之前在获取CallAdapter
类型的时候,已经调用了DefaultCallAdapterFactory.get
方法,所以executor
对象不为空,并且返回了一个匿名的CallAdapter
对象。
3、在上面我们调用DefaultCallAdapterFactory.adapt
方法时,就是调用了这个匿名对象的adapt
方法,这里返回的是ExecutorCallbackCall
对象。也就是说我们在做网络请求时就是使用这个ExecutorCallbackCall
对象。
执行请求
我们在上面的分析中知道,其实是ExecutorCallbackCall
对象进行网络请求,所以看一下它的源码。
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;
}
}
总结
到这里我们已经把Retrofit
的源码分析了一遍, 这里涉及大量的涉及模式,通过阅读Retrofit
的源码了解 ,更深入 理解这些设计模式使用.