前面已经分析了OkHttp源码的调用流程,通常会搭配Retrofit一起使用。笼统地说,Retrofit只是一个适配器,它内部封装了OkHttp,并不做实际的网络请求工作,而主要是为客户端调用网络请求和返回数据做适配,因此,我们说Retrofit只是一个适配器框架。同样的,先看下它的使用方法。
public interface RetrofitService {
@GET("users/{user}/repos")
Call<List<String>> listRepos(@Path("user") String user);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl( "https://api.github.com/" )//网络请求根地址,必须有,且末尾带/
.addConverterFactory( GsonConverterFactory.create() )//数据解析适配器
.addCallAdapterFactory( RxJava2CallAdapterFactory.create() )//请求适配器
.build();
//获取接口对象
RetrofitService retrofitService = retrofit.create( RetrofitService.class );
//获取OkHttpCall
Call repos = retrofitService.listRepos( "XXX" );
//同步请求
try {
Response execute = repos.execute();
} catch (IOException e) {
e.printStackTrace();
}
//异步请求
repos.enqueue( new Callback() {
@Override
public void onResponse(Call call, Response response) {
}
@Override
public void onFailure(Call call, Throwable t) {
}
} );
从示例看到,Retrofit只是做接口解析封装,这里的Call是Retrofit实现的一个装饰类,叫OkHttpCall,它持有OkHttp的Call ,即RealCall,由RealCall来做实际的网络请求。
下面我们先分析Retrofit的构建过程。
public static final class Builder {
//平台,默认是Android
private final Platform platform;
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;
Builder(Platform platform) {
this.platform = platform;
}
public Builder() {
this(Platform.get());
}
......
}
Retrofit也是用构建者模式进行创建的,它的Builder构造参数需传入一个Platform对象,这意味着,Retrofit不仅可以使用在Android平台,也可以使用在Java平台中。如果我们不传入指定平台,则会调用Platform.get(),它默认返回了Android对象。
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) {
}
//使用Java平台
return new Platform(true);
}
//获取默认请求适配器列表
List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
return hasJava8Types
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
//获取默认执行器
@Nullable Executor defaultCallbackExecutor() {
return null;
}
//Android平台
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
static class MainThreadExecutor implements Executor {
//主线程Handler
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
可以看到,Android是Platform 的静态内部类,并覆盖了defaultCallbackExecutor方法来,用于返回自己的Executor。而Android的Executor实现类是MainThreadExecutor,其本质是封装了主线程的Handler,来执行Runnable ,这表明,Retrofit是在主线程中执行的。
public static final class Builder {
//封装baseUrl为HttpUrl对象
public Builder baseUrl(String baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
//封装成HttpUrl,后进行检查
return baseUrl(HttpUrl.get(baseUrl));
}
//对baseUrl进行判断,并设置到成员变量
public Builder baseUrl(HttpUrl baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
//获取片段列表
List<String> pathSegments = baseUrl.pathSegments();
//最后一个字符必须是/
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
示例代码中,我们首先传入了基地址,它是必须设置的,并且字符串最后的“/”不能省略,否则会抛异常。
地址设置完成后,又调用了addConverterFactory传入数据适配器工厂GsonConverterFactory.create(),
public final class GsonConverterFactory extends Converter.Factory {
//创建方法
public static GsonConverterFactory create() {
return create(new Gson());
}
//传入Gson 对象
public static GsonConverterFactory create(Gson gson) {
return new GsonConverterFactory(gson);
}
//构造方法
private GsonConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
}
......
}
这里的逻辑比较简单,GsonConverterFactory 只是封装了 一个Gson对象。紧接着我们调用addCallAdapterFactory,设置了RxJava2CallAdapterFactory 适配器。
public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
public static RxJava2CallAdapterFactory create() {
return new RxJava2CallAdapterFactory(null);
}
private RxJava2CallAdapterFactory(Scheduler scheduler) {
this.scheduler = scheduler;
}
RxJava2CallAdapterFactory 继承了CallAdapter.Factory ,关于RxJava的原理将在<<RxJava源码>>中分析。
最终,构建时传入的参数都保留在Builder的成员变量中,Retrofit 会在buid方法中创建,并将参数传递过去,我们看Builder最后的build方法。
public static final class Builder {
......
public Retrofit build() {
//判断baseUrl不能为null
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//不自己配置OkHttpClient,则new OkHttpClient()
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//不实现自己的Executor ,则获取到MainThreadExecutor
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());
// 如果没有设置数据转换工厂则会使用默认的BuiltInConverters
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
//构建Retrofit
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
Retrofit构建完成后,则调用create方法获取接口对象。
public final class Retrofit {
//缓存ServiceMethod
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
// OkHttpClient
final okhttp3.Call.Factory callFactory;
//基地址
final HttpUrl baseUrl;
//将响应数据进行转换
final List<Converter.Factory> converterFactories;
// 适配器工厂
final List<CallAdapter.Factory> callAdapterFactories;
// 线程执行器
final 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; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
//通过动态代理创建具体的网络请求实体类
public <T> T create(final Class<T> service) {
validateServiceInterface(service);
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override public @Nullable Object invoke(Object proxy, Method method,
@Nullable Object[] args) throws Throwable {
// 如果是Object中的方法,则正常执行
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//如果是platform默认的方法则执行platform的方法
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//获取ServiceMethod执行invoke
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
//获取ServiceMethod
ServiceMethod<?> loadServiceMethod(Method method) {
//从缓存获取
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
//缓存不存在,则调用parseAnnotations创建
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
}
可以看到,Retrofit通过动态代理返回了接口代理对象,当我们调用接口方法时,将会执行代理类的invoke方法。
代理类的invoke里,前两个判断用来过滤Object类和Platform 的方法,我们通常不会调用到。而是调用到关键方法loadServiceMethod,它将根据接口方法的声明和返回类型,获取到一个ServiceMethod对象,并调用其invoke方法,这个ServiceMethod对象对应我们接口的返回类型。
Retrofit的成员变量serviceMethodCache以Method为key,value为ServiceMethod,对ServiceMethod进行缓存。因此loadServiceMethod会首先从缓存获取,如果缓存没有,则通过ServiceMethod的静态方法parseAnnotations来构建。
abstract class ServiceMethod<T> {
//获取ServiceMethod
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//解析接口,封装成RequestFactory
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
//接口返回类型不能为空
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
ServiceMethod是抽象类,它的子类是HttpServiceMethod。获取ServiceMethod时,ServiceMethod会先解析接口方法,并封装成RequestFactory 对象,再传递给HttpServiceMethod子类。因此,我们来看RequestFactory的parseAnnotations方法是如何解析的。
final class RequestFactory {
//通过Builder创建
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
static final class Builder {
......
final Retrofit retrofit;
final Method method;
final Annotation[] methodAnnotations;
final Annotation[][] parameterAnnotationsArray;
final Type[] parameterTypes;
......
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.).");
}
......
//解析形参注解参数
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);
}
......
//构建RequestFactory
return new RequestFactory(this);
}
通过对接口方法的注解、形参和形参注解的解析,RequestFactory对象便持有了接口声明的各参数,它们都以数组的形式保存了下来。
紧接着通过执行HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)方法,RequestFactory将被传递到ServiceMethod的子类HttpServiceMethod中。
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;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;
Annotation[] annotations = method.getAnnotations();
Type adapterType;
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType = Utils.getParameterLowerBound(0,
(ParameterizedType) parameterTypes[parameterTypes.length - 1]);
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
} else {
}
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
adapterType = method.getGenericReturnType();
}
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
if (responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (responseType == Response.class) {
throw methodError(method, "Response must include generic type (e.g., Response<String>)");
}
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}
@Override final @Nullable ReturnT invoke(Object[] args) {
//创建OkHttpCall
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
@Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
}
}
static final class SuspendForResponse<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;
SuspendForResponse(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, Call<ResponseT>> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
@Override protected Object adapt(Call<ResponseT> call, Object[] args) {
call = callAdapter.adapt(call);
Continuation<Response<ResponseT>> continuation =
(Continuation<Response<ResponseT>>) args[args.length - 1];
try {
return KotlinExtensions.awaitResponse(call, continuation);
} catch (Exception e) {
return KotlinExtensions.suspendAndThrow(e, continuation);
}
}
}
static final class SuspendForBody<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;
private final boolean isNullable;
SuspendForBody(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, Call<ResponseT>> callAdapter, boolean isNullable) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
this.isNullable = isNullable;
}
@Override protected Object adapt(Call<ResponseT> call, Object[] args) {
call = callAdapter.adapt(call);
Continuation<ResponseT> continuation = (Continuation<ResponseT>) args[args.length - 1];
try {
return isNullable
? KotlinExtensions.awaitNullable(call, continuation)
: KotlinExtensions.await(call, continuation);
} catch (Exception e) {
return KotlinExtensions.suspendAndThrow(e, continuation);
}
}
}
......
}
HttpServiceMethod也是抽象类,它增加了adapt抽象方法。由CallAdapted、SuspendForResponse、SuspendForBody这3个内部类继承。
由继承关系知道,ServiceMethod的invoke,实际由HttpServiceMethod来实现,它会先创建了一个OkHttpCall,上面提到它是一个装饰类,是对RealCall的封装。
final class OkHttpCall<T> implements Call<T> {
//接口参数对象
private final RequestFactory requestFactory;
//接口参数
private final Object[] args;
//OKHttpClient
private final okhttp3.Call.Factory callFactory;
//GsonConverterFactory
private final Converter<ResponseBody, T> responseConverter;
//是否取消请求
private volatile boolean canceled;
//原生call,即RealCall
@GuardedBy("this")
private @Nullable okhttp3.Call rawCall;
@GuardedBy("this")
private @Nullable Throwable creationFailure;
@GuardedBy("this")
private boolean executed;
OkHttpCall(RequestFactory requestFactory, Object[] args,
okhttp3.Call.Factory callFactory, Converter<ResponseBody, T> responseConverter) {
this.requestFactory = requestFactory;
this.args = args;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
}
由上面分析知道,最终请求调用是通过OkHttp的RealCall来操作的,我们先来看同步请求的调用流程。
final class OkHttpCall<T> implements Call<T> {
......
//同步请求
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
//将executed置为true
executed = true;
......
//首次调用rawCall为null
call = rawCall;
if (call == null) {
try {
//获取RealCall
call = rawCall = createRawCall();
} catch (IOException | RuntimeException | Error e) {
throwIfFatal(e);
creationFailure = e;
throw e;
}
}
}
//是否取消
if (canceled) {
call.cancel();
}
//解析ok返回的数据
return parseResponse(call.execute());
}
//创建RealCall
private okhttp3.Call createRawCall() throws IOException {
//通过OKHttpClient创建RealCall
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
//解析响应数据
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
......
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
//根据设置的数据解析器进行解析
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
catchingBody.throwIfCaught();
throw e;
}
}
通过OKHttpClient创建RealCall,来执行网络请求,这一部分的具体执行流程已在<<OkHttp源码>>做了分析。而当最后一步的parseResponse方法被调用,OkHttpCall会根据我们传入的数据解析器,将响应的网络数据进行解析,并返回给我们的上层调用。再来看异步请求调用流程。
final class OkHttpCall<T> implements Call<T> {
......
//异步请求
@Override public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(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 {
//获取RealCall
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();
}
}
//失败回调
@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
}
}
});
}
异步请求和同步请求的流程大致相同,最终通过接口回调给上层应用。
网友评论