本文旨在用简短的代码块完成对Retrofit大体流程的解析,不求甚解,适可而止,以防走丢(っ•̀ω•́)っ✎⁾⁾
Retrofit是对OkHttp的封装,应用程序通过Retrofit请求网络,实际是使用Retrofit接口层封装请求参数,之后由OkHttp完成后续的请求操作,在服务端返回数据之后,OkHttp将原始的结果交给Retrofit,Retrofit根据用户的需求对结果进行解析
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
public interface ApiService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Query("user")String user);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiService service = retrofit.create(ApiService.class);
Call<List<Repo>> call = service.listRepos("xxx");
call.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.new Retrofit.Builder()
看一下Builder的构造方法
public Builder() {
this(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");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
}
可以看到这里会得到一个平台类,包含Android或者Java8
回到开始,看一下baseUrl方法:
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
return baseUrl(HttpUrl.get(baseUrl));
}
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(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;
}
可以看到baseUrl必须非空,并且以"/"结尾
回到开始,看一下addConverterFactory方法:
private final List<Converter.Factory> converterFactories = new ArrayList<>();
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
一个数据转换工厂的集合,看一下GsonConverterFactory.create()方法:
public static GsonConverterFactory create() {
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
会创建gson对象,用于数据解析
回到开始,看一下build方法:
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();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
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.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
如果callFactory为空,会默认创建一个OkHttpClient对象;callbackExecutor回调执行器,若为空,调用platform.defaultCallbackExecutor()方法,因为我们是Android平台,找到Android类继承Platform:
static class Android extends Platform {
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
}
因为OkHttpClient数据回调在子线程,所以这个callbackExecutor是用于请求数据后,将线程切换到主线程
最后是请求适配器工厂集合callAdapterFactories和数据转换器converterFactories的初始化,将这些参数传入Retrofit中,返回Retrofit对象。
2.retrofit.create(ApiService.class)
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override
public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
validateServiceInterface方法就是对接口的判断抛出异常
static <T> void validateServiceInterface(Class<T> service) {
if (!service.isInterface()) {
throw new IllegalArgumentException("API declarations must be interfaces.");
}
// Prevent API interfaces from extending other interfaces. This not only avoids a bug in
// Android (http://b.android.com/58753) but it forces composition of API declarations which is
// the recommended pattern.
if (service.getInterfaces().length > 0) {
throw new IllegalArgumentException("API interfaces must not extend other interfaces.");
}
}
然后是eagerlyValidateMethods方法,提前验证
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {
loadServiceMethod(method);
}
}
}
boolean isDefaultMethod(Method method) {
return false;
}
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;
}
对method做一个缓存,缓存到map中
Proxy.newProxyInstance是使用动态代理,直接看最后一行loadServiceMethod方法,如果缓存中有就从缓存取出,没有就put进去。追踪invoke方法,在HttpServiceMethod里,它继承了ServiceMethod:
final class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
@Override
ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
}
进入adapt方法:
@Override
public CompletableFuture<R> adapt(final Call<R> call) {
final CompletableFuture<R> future = new CompletableFuture<R>() {
@Override public boolean cancel(boolean mayInterruptIfRunning) {
if (mayInterruptIfRunning) {
call.cancel();
}
return super.cancel(mayInterruptIfRunning);
}
};
call.enqueue(new Callback<R>() {
@Override public void onResponse(Call<R> call, Response<R> response) {
if (response.isSuccessful()) {
future.complete(response.body());
} else {
future.completeExceptionally(new HttpException(response));
}
}
@Override public void onFailure(Call<R> call, Throwable t) {
future.completeExceptionally(t);
}
});
return future;
}
注意这里的Call是Retrofit库中的,而不是OkHttp里的Call,进入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 {
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) {
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) {
t.printStackTrace();
}
}
});
}
到这一步,这里的Call就是okhttp3.Call了,也就是说Retrofit是对OkHttp请求的进一步封装。请求完之后,会对响应值rawResponse进行解析,追踪parseResponse方法:
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
向下查找convert的实现,到GsonResponseBodyConverter类中,就是进行json解析的地方
@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();
}
}