先从简单的使用开始
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
Retrofit 使用方法注解的方式把Java接口转化成HTTP请求
public interface GitHubService {
//获取github上用户所有的仓库
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
Retrofit使用四部曲
//1. 构建一个Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
//2. 生成一个GitHubService接口的实现
GitHubService service = retrofit.create(GitHubService.class);
//3. 创建一个请求
Call<List<Repo>> listCall = service.listRepos("octocat");
try {
//4. 同步执行
Response<List<Repo>> response = listCall.execute();
} catch (IOException e) {
e.printStackTrace();
}
//4. 异步执行
listCall.enqueue(new Callback<List<Repo>>() {
@Override
public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
}
@Override
public void onFailure(Call<List<Repo>> call, Throwable t) {
}
});
1.构建一个Retrofit实例。
首先看一下Retrofit.Builder类的构造函数
public Builder() {
this(Platform.get());
}
Builder(Platform platform) {
this.platform = platform;
}
Retrofit.Builder类的构造函数内部初始化了一个Platform实例。Platform代表Retrofit的使用平台。我们在Android中使用Retrofit,平台就是Android。
static class Android extends Platform {
//默认的回调执行器
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor
callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
//隐隐约约看到了熟悉的Handler。可以猜想,回调之所以是在主线程执行,还是使用handler来实现的
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
接下来看一下Retrofit.Builder类的build()方法
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//初始化callFactory
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//初始化回调执行器
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 防御性拷贝callAdapterFactories,并添加默认的Call adapter
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>
(this.callAdapterFactories);
//添加默认的Call adapter
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// 防御性拷贝converters,并添加内置的converter factory
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
//首先添加内置的converter factory到converter factory list中
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
Retrofit.Builder类的build()方法初始化了三个重要的成员,先记一下。
- okhttp3.Call.Factory callFactory:
- List<CallAdapter.Factory> callAdapterFactories
- List<Converter.Factory> converterFactories
最后Retrofit.Builder类的build()方法返回了一个Retrofit实例。
2. 生成一个GitHubService接口的实现
GitHubService service = retrofit.create(GitHubService.class);
public <T> T create(final Class<T> service) {
//1. 首先验证service是否合法
Utils.validateServiceInterface(service);
//2. 是否提前创建service里面的所有方法
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//3. 创建service的动态代理
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method,
@Nullable Object[] args)throws Throwable {
// service的所有方法调用,最终会转发到这里
// 如果是Object的方法,就正常调用
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//如果是default方法(Java8中的默认方法),Android中不用管,一定是false
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//3.1
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>)
loadServiceMethod(method);
//3.2
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//3.3
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
create()方法内部创建了我们传入的service的动态代理。就是说我们我们调用service中的任何方法,都会转发到这个动态代理的invoke()方法中。
3. 创建一个请求
Call<List<Repo>> listCall = service.listRepos("octocat");
这时,方法就转发到service动态代理的invoke()方法中了。
//3.1
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>)
loadServiceMethod(method);
//3.2
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//3.3
return serviceMethod.callAdapter.adapt(okHttpCall);
3.1构建一个ServiceMethod实例,ServiceMethod把对接口方法的调用转为一个HTTP调用
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>)
loadServiceMethod(method);
加载method对应的ServiceMethod。如果缓存中存在就直接返回,否则创建一个ServiceMethod加入缓存,然后返回。可见每个ServiceMethod只会创建一次。
//缓存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 = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
接下来看一下ServiceMethod.Builder这个类。ServiceMethod.Builder负责检查我们在接口中定义的方法上的注解,来构造一个可重复使用的服务方法。这个过程需要用到代价非常昂贵的反射操作,所以最好是只构建一个方法一次,然后重复使用它。Builder的实例不能被重用。
ServiceMethod.Builder的构造函数
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
ServiceMethod.Builder的build方法简化版
public ServiceMethod build() {
//1. 创建callAdapter
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
...
//2. 创建responseConverter
responseConverter = createResponseConverter();
//3. 处理方法注解
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
...
int parameterCount = parameterAnnotationsArray.length;
//4. 创建parameterHandlers
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
...
//5. 返回一个ServiceMethod实例
return new ServiceMethod<>(this);
}
- 创建callAdapter:把一个类型参数为R的
retrofit2.Call
转化成T类型的对象(Call<R>转化成T)。CallAdapter的实例由构建Retrofit时候通过{Retrofit.Builder#addCallAdapterFactory(Factory)}方法设置。
createCallAdapter()方法简化版
private CallAdapter<T, R> createCallAdapter() {
Type returnType = method.getGenericReturnType();
...
Annotation[] annotations = method.getAnnotations();
try {
//返回CallAdapter
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) {
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
可见CallAdapter还是由Retrofit提供的。
Retrofit的callAdapter()方法
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
Retrofit的nextCallAdapter()方法简化版
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast,
Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
//遍历callAdapterFactories,返回合适的CallAdapter
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType,
annotations, this);
if (adapter != null) {
return adapter;
}
}
Retrofit的callAdapter()方法内部会去遍历callAdapterFactories这个list,根据返回类型和注解,返回合适的callAdapter。
当我们构建一个默认的Retrofit实例的时候,在Retrofit.Builder的build()方法内部回传入一个平台相关的CallAdapter.Factory
public Retrofit build() {
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>
(this.callAdapterFactories);
//添加平台相关的CallAdapter.Factory
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
}
而Android平台相关的默认的CallAdapter.Factory就是ExecutorCallAdapterFactory。ExecutorCallAdapterFactory这个类暂且不去管他。现在算是找到ServiceMethod 的callAdapter了。
- 创建Converter<ResponseBody, T> responseConverter。负责把
okhttp3.ResponseBody
转化为T类型的对象。
private Converter<ResponseBody, T> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();
try {
//从retrofit中获取
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create converter for %s", responseType);
}
}
可见responseConverter还是由Retrofit提供的。
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type,
Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
int start = converterFactories.indexOf(skipPast) + 1;
//遍历converterFactories,找到合适的converter
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
}
Retrofit的responseBodyConverter()方法内部会去遍历converterFactories这个list,根据返回类型和注解,返回合适的responseConverter。
当我们构建一个默认的Retrofit实例的时候,在Retrofit.Builder的build()方法内部回传入一个内置的BuiltInConverters
public Retrofit build() {
...
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories =
new ArrayList<>(1 + this.converterFactories.size());
// 首先添加一个内置的converter factory
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
BuiltInConverters这个类暂且不去管它。现在为ServiceMethod找到了responseConverter。
-
parseMethodAnnotation:负责解析检查方法注解,暂且略过。
-
创建parameterHandlers,负责解析 API 定义时每个方法的参数,并在构造 HTTP 请求时设置参数;这个过程暂且不去看。
每个参数都会有一个 ParameterHandler,由 ServiceMethod#parseParameter 方法负责创建,其主要内容就是解析每个参数使用的注解类型(诸如 Path,Query,Field 等),对每种类型进行单独的处理。API 方法中除了 @Body 和 @Part 类型的参数,都利用 Converter.Factory.stringConverter 进行转换,而 @Body 和 @Part 类型的参数则利用 Converter.Factory.requestBodyConverter 进行转换。
现在ServiceMethod.Builder的build()方法可以返回一个实例了。
public ServiceMethod build() {
//5. 返回一个ServiceMethod实例
return new ServiceMethod<>(this);
}
3.2现在是创建一个OkHttpCall实例
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
3.3 返回结果
return serviceMethod.callAdapter.adapt(okHttpCall);
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
我们构建Retrofit实例的时候,默认会为我们添加一个平台相关的defaultCallAdapterFactory。
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
//Android平台传入的是MainThreadExecutor
return new ExecutorCallAdapterFactory(callbackExecutor);
}
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
//回调执行器
final Executor callbackExecutor;
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
//实现了retrofit2.Call接口
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
//调用代理的enqueue方法,并在执行完毕后使用回调执行器切换线程
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
//执行成功,使用回调执行器切换线程
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
//执行失败,切换线程
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
@Override public boolean isExecuted() {
return delegate.isExecuted();
}
//调用代理对象的execute()方法
@Override public Response<T> execute() throws IOException {
return delegate.execute();
}
@Override public void cancel() {
delegate.cancel();
}
@Override public boolean isCanceled() {
return delegate.isCanceled();
}
@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
@Override public Call<T> clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override public Request request() {
return delegate.request();
}
}
}
我们调用默认的CallAdapterFactory的get()方法,创建了一个CallAdapter的匿名内部类。
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
//返回一个CallAdapter实例。
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
//返回ExecutorCallbackCall实例
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
CallAdapter的adapt()方法返回了一个ExecutorCallbackCall实例。ExecutorCallbackCall内部的execute()和enqueue()方法,就是调用被代理对象的方法。如果是调用被代理对象的enqueue()方法,并在执行完毕后使用回调执行器切换线程。这里的被代理对象就是我们传入的OkHttpCall的实例。再贴一下代码。
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>)
loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
4. 现在到了Retrofit使用四部曲的第四步,执行请求。
4.1 同步请求execute(),ExecutorCallbackCall内部的execute()就是调用了代理对象的execute()方法。
@Override public Response<T> execute() throws IOException {
return delegate.execute();
}
OkHttpCall的execute方法。
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
//1. 一个请求只能被执行一次
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
//2. 创建一个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();
}
//3. 转换okhttp3.Call的执行返回的响应
return parseResponse(call.execute());
}
- 一个请求只能被执行一次。
- createRawCall()方法,创建一个okhttp3.Call
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = serviceMethod.toCall(args);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
createRawCall()方法返回的是一个okhttp3.RealCall的实例。
- 转换okhttp3.Call的执行返回的响应
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
//1. 单独把响应体取出来
ResponseBody rawBody = rawResponse.body();
//移除rawResponse的本来的响应体,传入一个没有内容的响应体
rawResponse = rawResponse.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
//缓存整个原始响应体,避免将来可能出现的I/O异常
ResponseBody bufferedBody = Utils.buffer(rawBody);
//构建一个错误的响应返回,并把bufferedBody作为错误的响应体
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) {
rawBody.close();
//构建一个正确的响应返回,但是响应体为null
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
//把原始响应体转化成我们希望的数据类型
T body = serviceMethod.toResponse(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;
}
}
parseResponse首先会对响应做一些预处理,如果没有什么异常的话,就构建一个成功的响应返回。返回的响应的响应体就是我们希望的数据类型。
4.2 异步请求execute(),ExecutorCallbackCall内部的execute()就是调用了代理对象的execute()方法。
OkHttpCall的enqueue()方法
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
//1.构建一个okhttp3.Call
call = rawCall = createRawCall();
} catch (Throwable t) {
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
//2. 使用okhttp3.Call的enqueue方法
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response<T> response;
try {
//把okhttp3.Response转换成retrofit2的Response
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
//3. 成功的回调
callSuccess(response);
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
try {
//4. 失败的回调
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callSuccess(Response<T> response) {
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
OkHttpCall的enqueue()方法和execute()方法一样,先判断请求是否执行过了。如果没有执行,就构建一个okhttp3.Call的实例。和execute()方法不同的是,这里使用了okhttp3.Call的enqueue()方法。
至此:Retrofit使用四部曲就分析完了。
网友评论