前言
現(xiàn)代Android開發(fā)中,Retrofit是主流的網(wǎng)絡(luò)請(qǐng)求框架,內(nèi)部封裝OkHttp發(fā)起請(qǐng)求,也是聲明式Http客戶端,使用接口 + 注解的方式在接口中編寫請(qǐng)求方法。
簡單使用
先看下常規(guī)Retrofit的使用吧,也是通過入口API來看源碼的一種好方法。
我們先來看不添加Convert轉(zhuǎn)換器的方式,這種方式只能設(shè)置返回值中的泛型為ResponseBody,拿到的數(shù)據(jù)只能是Json字符串,而轉(zhuǎn)換模型的操作需要我們自己做,當(dāng)然如果是添加了轉(zhuǎn)換器,則可以直接寫模型的泛型了
- 編寫請(qǐng)求方法的接口
public interface WanAndroid {
/**
* Retrofit Call,獲取首頁文章列表,如果不添加轉(zhuǎn)換器,則泛型只能是ResponseBody
*/
@GET("article/list/{page}/json")
Call<ResponseBody> getHomeArticleByCall(@Path("page") int page);
}
- 創(chuàng)建Retroft實(shí)例
//創(chuàng)建Retrofit實(shí)例
Retrofit retrofit = new Retrofit.Builder()
//配置OkHttpClient
.callFactory(new OkHttpClient.Builder().build())
//配置基礎(chǔ)Url
.baseUrl("https://www.wanandroid.com")
//開始創(chuàng)建
.build();
//創(chuàng)建服務(wù)接口
WanAndroid wanAndroid = mRetrofit.create(WanAndroid.class);
- 發(fā)起請(qǐng)求,沒有添加轉(zhuǎn)換器,需要自己做轉(zhuǎn)換,代碼太惡心了
wanAndroid.getHomeArticleByCall(page).enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
//解析Json,轉(zhuǎn)換為模型
String json = response.body().string();
Gson gson = new Gson();
Type type = new TypeToken<HttpModel<PageModel<HomeArticleModel>>>() {
}.getType();
HttpModel<PageModel<HomeArticleModel>> model = gson.fromJson(json, type);
//請(qǐng)求成功
} catch (IOException e) {
e.printStackTrace();
//請(qǐng)求失敗
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable throwable) {
ToastUtil.toast(getContext(), "請(qǐng)求失敗:" + throwable.getMessage());
}
});
開始分析
從簡單使用來看,我們發(fā)現(xiàn)以下幾點(diǎn)
- Retrofit的實(shí)例創(chuàng)建,通過Builder構(gòu)建者模式,通過鏈?zhǔn)骄幊踢M(jìn)行Retrofit的配置,最后通過build()方法創(chuàng)建實(shí)例
- 請(qǐng)求的方法,都放在接口上,通過Retrofit的create()方法,創(chuàng)建接口的實(shí)例
- API接口的方法返回值為Call,它是Retrofit中的一個(gè)類
Retrofit實(shí)例創(chuàng)建
簡單來講,就是把Retrofit的構(gòu)造方法私有,只能通過內(nèi)部的Builder內(nèi)部類的實(shí)例創(chuàng)建,所以我們對(duì)Retrofit的配置,都是配置到Retrofit內(nèi)的Builder類后,再通過它的build方法,創(chuàng)建Retrofit實(shí)例。
public final class Retrofit {
/**
* OkHttpClient
*/
final okhttp3.Call.Factory callFactory;
/**
* 基礎(chǔ)Url
*/
final HttpUrl baseUrl;
/**
* Converter轉(zhuǎn)換器工廠列表
*/
final List<Converter.Factory> converterFactories;
/**
* CallAdapter適配器工廠列表
*/
final List<CallAdapter.Factory> callAdapterFactories;
/**
* 回調(diào)執(zhí)行器
*/
final @Nullable
Executor callbackExecutor;
/**
* 是否創(chuàng)建接口實(shí)例時(shí)就校驗(yàn)接口的合法性,默認(rèn)為false,在調(diào)用接口的方法時(shí),才校驗(yàn)
*/
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;
}
/**
* 使用Builder構(gòu)建者模式
*/
public static final class Builder {
/**
* 平臺(tái)
*/
private final Platform platform;
/**
* OkHttpClient
*/
private @Nullable
okhttp3.Call.Factory callFactory;
/**
* 基礎(chǔ)路徑
*/
private @Nullable
HttpUrl baseUrl;
/**
* 注冊的Converter轉(zhuǎn)換器工廠
*/
private final List<Converter.Factory> converterFactories = new ArrayList<>();
/**
* 注冊的CallAdapter適配器工廠
*/
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
/**
* 回調(diào)時(shí)使用的執(zhí)行器
*/
private @Nullable
Executor callbackExecutor;
/**
* 是否馬上檢查API接口的合法性
*/
private boolean validateEagerly;
Builder(Platform platform) {
this.platform = platform;
}
public Builder() {
this(Platform.get());
}
/**
* 直接拷貝另外一個(gè)Retrofit實(shí)例的配置到Builder
*/
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;
}
/**
* 設(shè)置OkHttpClient
*/
public Builder client(OkHttpClient client) {
return callFactory(Objects.requireNonNull(client, "client == null"));
}
/**
* 設(shè)置OkHttpClient
*/
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = Objects.requireNonNull(factory, "factory == null");
return this;
}
/**
* 配置URL類型的基礎(chǔ)Url
*/
public Builder baseUrl(URL baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
return baseUrl(HttpUrl.get(baseUrl.toString()));
}
/**
* 配置String類型基礎(chǔ)Url
*/
public Builder baseUrl(String baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
return baseUrl(HttpUrl.get(baseUrl));
}
/**
* 配置HttpUrl類型基礎(chǔ)Url
*/
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;
}
/**
* 添加一個(gè)Converter工廠
*/
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
/**
* 添加一個(gè)CallAdapter工廠
*/
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(Objects.requireNonNull(factory, "factory == null"));
return this;
}
/**
* 配置回調(diào)執(zhí)行器
*/
public Builder callbackExecutor(Executor executor) {
this.callbackExecutor = Objects.requireNonNull(executor, "executor == null");
return this;
}
/**
* 返回注冊的CallAdapter工廠
*/
public List<CallAdapter.Factory> callAdapterFactories() {
return this.callAdapterFactories;
}
/**
* 返回注冊的Converter工廠
*/
public List<Converter.Factory> converterFactories() {
return this.converterFactories;
}
/**
* 配置是否迫切校驗(yàn)接口上的方法
*/
public Builder validateEagerly(boolean validateEagerly) {
this.validateEagerly = validateEagerly;
return this;
}
/**
* 構(gòu)建一個(gè)Retrofit實(shí)例
*/
public Retrofit build() {
//必須設(shè)置基礎(chǔ)路徑
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
//外部沒有配置,創(chuàng)建默認(rèn)配置的OkHttpClient
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//外部沒有配置,自動(dòng)從平臺(tái)中拿
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);
//默認(rèn)添加一個(gè)CallAdapter工廠,支持Call類型的返回值
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.
//默認(rèn)添加一個(gè)Converter工廠,支持返回值的泛型為RequestBody類型
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
//從平臺(tái)中拿Converter工廠,不同平臺(tái)可以有不同的支持,如果支持Java8,則會(huì)添加一個(gè)Option類型的支持
converterFactories.addAll(platform.defaultConverterFactories());
//創(chuàng)建實(shí)例
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
}
}
}
- Platform類,請(qǐng)求響應(yīng)回調(diào)在主線程的關(guān)鍵
在Builder的構(gòu)造方法中,調(diào)用了Platform類的get方法,這個(gè)類是適配調(diào)用平臺(tái)的,因?yàn)镽etrofit的接口請(qǐng)求在子線程請(qǐng)求,而接口響應(yīng)的回調(diào)方法,是可以在Android的主線程中回調(diào)的,這就肯定會(huì)涉及到Handler,而Retrofit也支持在鴻蒙上使用,這時(shí)就需要拓展Platfrom類來實(shí)現(xiàn)
可以看到,如果在Android平臺(tái)運(yùn)行,則返回的是Android實(shí)現(xiàn)類,該類復(fù)寫了defaultCallbackExecutor()方法,返回MainThreadExecutor實(shí)例,這個(gè)Executor其實(shí)是線程池接口,只有一個(gè)execute()方法,MainThreadExecutor類復(fù)寫了execute()方法,通過Handler把傳進(jìn)來的Runnable轉(zhuǎn)發(fā)到主線程進(jìn)行回調(diào)
class Platform {
/**
* 單例,查找到后,后續(xù)再調(diào)用不會(huì)再次查找
*/
private static final Platform PLATFORM = findPlatform();
/**
* 獲取Platform實(shí)例的方法
*/
static Platform get() {
return PLATFORM;
}
/**
* 查找當(dāng)前平臺(tái)的實(shí)現(xiàn)
*/
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
//安卓
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
//ignored
}
//Java8
return new Platform(true);
}
/**
* 是否支持Java8
*/
private final boolean hasJava8Types;
private final @Nullable
Constructor<Lookup> lookupConstructor;
Platform(boolean hasJava8Types) {
this.hasJava8Types = hasJava8Types;
Constructor<Lookup> lookupConstructor = null;
if (hasJava8Types) {
try {
// Because the service interface might not be public, we need to use a MethodHandle lookup
// that ignores the visibility of the declaringClass.
lookupConstructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
lookupConstructor.setAccessible(true);
} catch (NoClassDefFoundError ignored) {
// Android API 24 or 25 where Lookup doesn't exist. Calling default methods on non-public
// interfaces will fail, but there's nothing we can do about it.
} catch (NoSuchMethodException ignored) {
// Assume JDK 14+ which contains a fix that allows a regular lookup to succeed.
// See https://bugs.openjdk.java.net/browse/JDK-8209005.
}
}
this.lookupConstructor = lookupConstructor;
}
@Nullable
Executor defaultCallbackExecutor() {
return null;
}
List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
//默認(rèn)的CallAdapterFactory,支持Call類型的返回值
DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
return hasJava8Types
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
int defaultCallAdapterFactoriesSize() {
return hasJava8Types ? 2 : 1;
}
List<? extends Converter.Factory> defaultConverterFactories() {
return hasJava8Types ? singletonList(OptionalConverterFactory.INSTANCE) : emptyList();
}
int defaultConverterFactoriesSize() {
return hasJava8Types ? 1 : 0;
}
boolean isDefaultMethod(Method method) {
return hasJava8Types && method.isDefault();
}
@Nullable
Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object, Object... args)
throws Throwable {
Lookup lookup =
lookupConstructor != null
? lookupConstructor.newInstance(declaringClass, -1 /* trusted */)
: MethodHandles.lookup();
return lookup.unreflectSpecial(method, declaringClass).bindTo(object).invokeWithArguments(args);
}
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Nullable
@Override
Object invokeDefaultMethod(
Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
if (Build.VERSION.SDK_INT < 26) {
throw new UnsupportedOperationException(
"Calling default methods on API 24 and 25 is not supported");
}
return super.invokeDefaultMethod(method, declaringClass, object, args);
}
/**
* 安卓主線程執(zhí)行器
*/
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable task) {
handler.post(task);
}
}
}
}
API接口實(shí)例創(chuàng)建
Http接口的實(shí)現(xiàn),是通過create()方法創(chuàng)建的,內(nèi)部使用的是JDK的動(dòng)態(tài)代理,當(dāng)我們調(diào)用代理類的方法時(shí),會(huì)回調(diào)InvocationHandler的invoke()方法
- create(),動(dòng)態(tài)代理接口的實(shí)現(xiàn)
/**
* 傳入一個(gè)API接口類的Class,動(dòng)態(tài)代理該接口的實(shí)例
*/
@SuppressWarnings("unchecked")
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 {
//如果調(diào)用的是Object的方法,直接調(diào)用,不需要處理
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//沒有參數(shù),也用一個(gè)空數(shù)組
args = args != null ? args : emptyArgs;
//如果是default默認(rèn)方法,直接調(diào)用
return platform.isDefaultMethod(method) ? platform.invokeDefaultMethod(method, service, proxy, args)
//普通方法,進(jìn)行加載和解析,然后進(jìn)行調(diào)用
: loadServiceMethod(method).invoke(args);
}
});
}
- validateServiceInterface(),檢查API接口的合法性
/**
* 檢查API接口Class
*/
private void validateServiceInterface(Class<?> service) {
//傳入的Class必須是接口類
if (!service.isInterface()) {
throw new IllegalArgumentException("API declarations must be interfaces.");
}
Deque<Class<?>> check = new ArrayDeque<>(1);
check.add(service);
while (!check.isEmpty()) {
Class<?> candidate = check.removeFirst();
if (candidate.getTypeParameters().length != 0) {
StringBuilder message =
new StringBuilder("Type parameters are unsupported on ").append(candidate.getName());
if (candidate != service) {
message.append(" which is an interface of ").append(service.getName());
}
throw new IllegalArgumentException(message.toString());
}
Collections.addAll(check, candidate.getInterfaces());
}
//是否創(chuàng)建的時(shí)候就校驗(yàn),默認(rèn)為false,當(dāng)調(diào)用接口方法時(shí)才校驗(yàn),如果配置為true,則創(chuàng)建接口代理實(shí)現(xiàn)類時(shí)就校驗(yàn)
if (validateEagerly) {
Platform platform = Platform.get();
//遍歷接口上的方法
for (Method method : service.getDeclaredMethods()) {
//不檢查default默認(rèn)方法和靜態(tài)方法
if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
loadServiceMethod(method);
}
}
}
}
- loadServiceMethod(),加載接口方法
在InvocationHandler類的invoke()方法中,如果調(diào)用的是Object類的方法,直接調(diào)用,如果是Java8的默認(rèn)方法,直接調(diào)用。最后就是普通的API方法,則調(diào)用loadServiceMethod(),這個(gè)方法的作用是解析API方法,并緩存到一個(gè)Map中,下次調(diào)用是直接復(fù)用的,最終是需要返回一個(gè)不為null的ServiceMethod實(shí)例,再調(diào)用它的invoke()執(zhí)行方法調(diào)用
/**
* 接口方法信息的緩存
*/
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
/**
* 加載接口方法
*/
ServiceMethod<?> loadServiceMethod(Method method) {
//優(yōu)先從緩存中取,取得到則返回,不需要每次調(diào)用都處理一次,浪費(fèi)性能
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) {
return result;
}
//Double Check + 同步鎖,確保多線程調(diào)用時(shí)真的找不到緩存
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
//真的沒有,解析方法上的注解
result = ServiceMethod.parseAnnotations(this, method);
//解析完,放到緩存
serviceMethodCache.put(method, result);
}
}
return result;
}
- ServiceMethod.parseAnnotations,解析方法上的注解
loadServiceMethod ()中,如果沒有命中緩存,則通過ServiceMethod.parseAnnotations(),解析方法注解,返回ServiceMethod實(shí)例,再緩存起來
其中,ServiceMethod是一個(gè)抽象類
abstract class ServiceMethod<T> {
/**
* 解析注解
*/
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//解析接口上的請(qǐng)求方法的注解,以及方法形參上的注解,并把信息轉(zhuǎn)換為RequestFactory實(shí)例
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);
}
//返回值的泛型不能是Void類型
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
//進(jìn)行返回值適配和轉(zhuǎn)換器
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
/**
* 執(zhí)行方法
*
* @param args 方法參數(shù)
*/
abstract @Nullable
T invoke(Object[] args);
}
- RequestFactory.parseAnnotations(),解析接口上的請(qǐng)求方法的注解,以及方法形參上的注解,并把信息轉(zhuǎn)換為RequestFactory實(shí)例
RequestFactory類也是一個(gè)Builder建造者模式,只是它是通過Builder類拆解Method對(duì)象,再通過build方法開始解析方法上的注解
注解分2種,分別是:方法級(jí)的注解和方法形參上的注解,方法級(jí)的注解是@GET、@POST這種作用于方法上的注解,而方法形參上的注解則是@Path、@Field這種作用于形參上的注解
最后返回RequestFactory實(shí)例,最后調(diào)用HttpServiceMethod.parseAnnotations(),進(jìn)行返回值適配和轉(zhuǎn)換器
final class RequestFactory {
/**
* 解析方法上的注解
*/
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
//把方法上的注解進(jìn)行解析,并封裝到RequestFactory類上
return new Builder(retrofit, method).build();
}
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);
final Retrofit retrofit;
final Method method;
final Annotation[] methodAnnotations;
final Annotation[][] parameterAnnotationsArray;
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;
/**
* 把方法上的注解、返回值、方法形參上的注解保存
*/
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() {
//解析方法級(jí)的注解
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
//方法必須加上請(qǐng)求方式的注解,例如GET、POST
if (httpMethod == null) {
throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
//沒有Body
if (!hasBody) {
//不能是文件請(qǐng)求,肯定是使用了@GET注解,必須要使用@POST
if (isMultipart) {
throw methodError(
method,
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
//不能是表單請(qǐng)求(表單請(qǐng)求是放在body上的)
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]);
}
//不是相對(duì)路徑的Url,必須添加@Url注解,指定完全路徑的Url
if (relativeUrl == null && !gotUrl) {
throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
}
//沒有請(qǐng)求體的請(qǐng)求方式,不能加@Body注解
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError(method, "Non-body HTTP method cannot contain @Body.");
}
//表單請(qǐng)求,必須要有一個(gè)參數(shù)要有@Field的參數(shù)
if (isFormEncoded && !gotField) {
throw methodError(method, "Form-encoded method must contain at least one @Field.");
}
//文件請(qǐng)求,必須要有一個(gè)參數(shù)要有@Field的參數(shù)
if (isMultipart && !gotPart) {
throw methodError(method, "Multipart method must contain at least one @Part.");
}
return new RequestFactory(this);
}
}
}
- HttpServiceMethod.parseAnnotations,進(jìn)行返回值適配和轉(zhuǎn)換器
ServiceMethod是一個(gè)抽象類,通過ServiceMethod.parseAnnotations()靜態(tài)方法,會(huì)返回其子類HttpServiceMethod,子類的創(chuàng)建則是通過HttpServiceMethod.parseAnnotations()創(chuàng)建
通過解析方法的返回值,調(diào)用createCallAdapter(),查找能適配返回值的CallAdapter,再調(diào)用createResponseConverter()查找對(duì)應(yīng)的Converter轉(zhuǎn)換器
發(fā)現(xiàn),HttpServiceMethod也是一個(gè)抽象類,它在ServiceMethod的invoke()基礎(chǔ)上,調(diào)用了一個(gè)adapt()抽象方法,其子類CallAdapted,復(fù)寫了該方法,最終invoke()方法是通過CallAdapter來進(jìn)行處理
/**
* 一個(gè)把接口上的方法,轉(zhuǎn)換為Http調(diào)用的ServiceMethod
*/
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
private final RequestFactory requestFactory;
private final okhttp3.Call.Factory callFactory;
private final Converter<ResponseBody, ResponseT> responseConverter;
HttpServiceMethod(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter) {
this.requestFactory = requestFactory;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
}
/**
* 解析方法上的注解
*/
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
//獲取方法上的注解和返回值
Annotation[] annotations = method.getAnnotations();
Type adapterType = method.getGenericReturnType();
//找到支持適配返回值類型的CallAdapter
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
//泛型不能為okhttp3的Response,你會(huì)不會(huì)是想要ResponseBody
if (responseType == okhttp3.Response.class) {
throw methodError(
method,
"'"
+ getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
//Response必須要有泛型
if (responseType == Response.class) {
throw methodError(method, "Response must include generic type (e.g., Response<String>)");
}
// TODO support Unit for Kotlin?
//頂層方法必須沒有返回值,例如public void static main() {}
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
//找到對(duì)應(yīng)的轉(zhuǎn)換器
Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
//創(chuàng)建支持適配工作的HttpServiceMethod,就是復(fù)寫adapt()方法,并使用適配器進(jìn)行轉(zhuǎn)換
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
/**
* 找到支持適配返回值類型的CallAdapter
*/
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
try {
//noinspection unchecked
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);
}
}
/**
* 找到對(duì)應(yīng)的轉(zhuǎn)換器
*/
private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
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);
}
}
/**
* 執(zhí)行方法調(diào)用
*/
@Override
final @Nullable
ReturnT invoke(Object[] args) {
//創(chuàng)建Call實(shí)例
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
//進(jìn)行適配后返回結(jié)果
return adapt(call, args);
}
/**
* 適配方法
*/
protected abstract @Nullable
ReturnT adapt(Call<ResponseT> call, Object[] args);
/**
* 支持進(jìn)行適配的HttpServiceMethod子類
*/
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) {
//使用CallAdapter適配請(qǐng)求的返回值
return callAdapter.adapt(call);
}
}
}
CallAdapter適配器
- createCallAdapter,查找適配器
查找適配器的工作,發(fā)現(xiàn)是通過Retrofit實(shí)例callAdapter()方法,for循環(huán)查找注冊的適配器,如果沒有找到則拋異常,這實(shí)際上是策略模式的應(yīng)用
public final class Retrofit {
/**
* 返回可以適配返回值類型的CallAdapter實(shí)例
*
* @throws IllegalArgumentException 如果沒有找到,拋出異常
*/
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
/**
* 返回可以適配返回值類型的CallAdapter實(shí)例
*
* @throws IllegalArgumentException 如果沒有找到,拋出異常
*/
public CallAdapter<?, ?> nextCallAdapter(
@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
Objects.requireNonNull(returnType, "returnType == null");
Objects.requireNonNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
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());
}
}
- CallAdapter和CallAdapter.Factory
CallAdapter.Factory是CallAdapter的工廠類,每次發(fā)起請(qǐng)求,都是通過CallAdapter.Factory創(chuàng)建一個(gè)CallAdapter進(jìn)行適配工作
主要方法是Factory.get(),創(chuàng)建CallAdapter,而CallAdapter的主要方法是adapt,該方法對(duì)Call類進(jìn)行適配,以及responseType(),該方法返回該適配器能處理的返回值類型中的泛型Type
在Retrofit構(gòu)建時(shí),就添加了一個(gè)默認(rèn)的CallAdapter.Factory實(shí)例,它就是DefaultCallAdapterFactory,所以就是我們什么都不配置,默認(rèn)找到的CallAdapter.Factory就是DefaultCallAdapterFactory
/**
* 適配器,把Call中的泛型適配為返回值中的泛型
*/
public interface CallAdapter<R, T> {
/**
* 獲取適配后的類型,例如{@code Call<Repo>},返回的是Repo的Type對(duì)象
*/
Type responseType();
/**
* 把Call<R>適配為對(duì)應(yīng)的返回值類型的泛型
*/
T adapt(Call<R> call);
/**
* CallAdapter工廠,每次請(qǐng)求都會(huì)通過這個(gè)工廠生產(chǎn)CallAdapter
*/
abstract class Factory {
/**
* 對(duì)方法進(jìn)行適配,如果適配不了,返回null
*/
public abstract @Nullable
CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit);
/**
* 獲取泛型的上界類型,例如{@Code Map<String, ? extends Runnable>},會(huì)返回Runnable
*/
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
/**
* 獲取原始類型,例如{@code List<? extends Runnable>},會(huì)返回List
*/
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
- DefaultCallAdapterFactory,默認(rèn)的CallAdapter工廠
發(fā)現(xiàn)這個(gè)工廠類,在get()方法中,創(chuàng)建了一個(gè)CallAdapter的匿名內(nèi)部類,responseType()返回了Call中的泛型Type,然后adapt()方法創(chuàng)建了一個(gè)ExecutorCallbackCall類,該類實(shí)現(xiàn)了Call接口
它其實(shí)是一個(gè)裝飾器,包裝了當(dāng)前請(qǐng)求的Call類實(shí)例,并把enqueue()方法中的回調(diào)通過callbackExecutor做了調(diào)用包裝,這個(gè)callbackExecutor就是Platform類中的MainThreadExecutor實(shí)例,所以就是這里來做回調(diào)的主線程回調(diào)的!
/**
* 默認(rèn)的CallAdapter工廠
*/
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
/**
* 回調(diào)執(zhí)行器
*/
private final @Nullable
Executor callbackExecutor;
DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
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>");
}
//獲取Call中的泛型
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
//是否添加了SkipCallbackExecutor注解,如果添加了該注解,會(huì)不使用配置的callbackExecutor進(jìn)行回調(diào)
final Executor executor =
Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
? null
: callbackExecutor;
//創(chuàng)建一個(gè)CallAdapter,把數(shù)據(jù)原封不動(dòng)返回
return new CallAdapter<Object, Call<?>>() {
@Override
public Type responseType() {
return responseType;
}
@Override
public Call<Object> adapt(Call<Object> call) {
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}
};
}
/**
* 裝飾器,帶回調(diào)執(zhí)行器的Call,因?yàn)樵贠kHttpCall中的回調(diào)都是子線程回調(diào)的,這里可以再轉(zhuǎn)到主線程進(jìn)行回調(diào)
*/
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) {
Objects.requireNonNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override
public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(
() -> {
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(() -> callback.onFailure(ExecutorCallbackCall.this, t));
}
});
}
@Override
public boolean isExecuted() {
return delegate.isExecuted();
}
@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();
}
@Override
public Timeout timeout() {
return delegate.timeout();
}
}
}
Converter轉(zhuǎn)換器
CallAdapter查找完后,再查找Converter轉(zhuǎn)換器,它的邏輯和上面查找CallAdapter很類似,都是在Retrofit的實(shí)例上找,Converter也有一個(gè)Factory工廠類
public final class Retrofit {
/**
* 獲取支持返回值中的泛型為ResponseBody的Converter轉(zhuǎn)換器
*/
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
/**
* 獲取支持返回值中的泛型為ResponseBody的Converter轉(zhuǎn)換器
*
* @param skipPast 可以指定跳過某個(gè)轉(zhuǎn)換器
*/
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
Objects.requireNonNull(type, "type == null");
Objects.requireNonNull(annotations, "annotations == null");
int start = converterFactories.indexOf(skipPast) + 1;
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;
}
}
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());
}
}
- Converter.Factory,轉(zhuǎn)換器工廠
同樣,每次請(qǐng)求則創(chuàng)建都通過Factory創(chuàng)建一個(gè)Converter實(shí)例,Converter有2種
responseBodyConverter(),把ResponseBody轉(zhuǎn)換為Type類型的模型(請(qǐng)求響應(yīng)回來時(shí)調(diào)用),就是負(fù)責(zé)把接口響應(yīng)的json數(shù)據(jù),轉(zhuǎn)換為對(duì)應(yīng)的模型類
requestBodyConverter(),把Type模型轉(zhuǎn)換為RequestBody,就是application/json這種類型的請(qǐng)求,把模型類轉(zhuǎn)換為Json字符串,然后把Json字符串設(shè)置到RequestBody中
public interface Converter<F, T> {
/**
* 轉(zhuǎn)換方法
*/
@Nullable
T convert(F value) throws IOException;
/**
* Converter轉(zhuǎn)換器的工廠
*/
abstract class Factory {
/**
* 把ResponseBody轉(zhuǎn)換為Type類型的模型(請(qǐng)求響應(yīng)回來時(shí)調(diào)用)
*/
public @Nullable
Converter<ResponseBody, ?> responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
return null;
}
/**
* 把Type模型轉(zhuǎn)換為RequestBody(application/json請(qǐng)求前調(diào)用)
*/
public @Nullable
Converter<?, RequestBody> requestBodyConverter(
Type type,
Annotation[] parameterAnnotations,
Annotation[] methodAnnotations,
Retrofit retrofit) {
return null;
}
/**
* 把RequestBody轉(zhuǎn)換為String類型的Converter
*/
public @Nullable
Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return null;
}
/**
* 獲取泛型的上界類型,例如{@Code Map<String, ? extends Runnable>},會(huì)返回Runnable
*/
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
/**
* 獲取原始類型,例如{@code List<? extends Runnable>},會(huì)返回List
*/
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
- BuiltInConverters,默認(rèn)的轉(zhuǎn)換器工廠
在Retrofit實(shí)例創(chuàng)建中,也默認(rèn)添加了一個(gè)轉(zhuǎn)換器工廠,它就是BuiltInConverters
/**
* 默認(rèn)的Converter轉(zhuǎn)換器工廠
*/
final class BuiltInConverters extends Converter.Factory {
@Override
public @Nullable
Converter<ResponseBody, ?> responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
//方法的返回值中的泛型,是ResponseBody時(shí)才可以使用
if (type == ResponseBody.class) {
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
//泛型為Void
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
@Override
public @Nullable
Converter<?, RequestBody> requestBodyConverter(
Type type,
Annotation[] parameterAnnotations,
Annotation[] methodAnnotations,
Retrofit retrofit) {
//方法的形參有RequestBody時(shí)使用
if (RequestBody.class.isAssignableFrom(Utils.getRawType(type))) {
return RequestBodyConverter.INSTANCE;
}
return null;
}
/**
* 返回值的泛型是Void時(shí)使用
*/
static final class VoidResponseBodyConverter implements Converter<ResponseBody, Void> {
static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();
@Override
public Void convert(ResponseBody value) {
value.close();
return null;
}
}
/**
* RequestBody轉(zhuǎn)換器
*/
static final class RequestBodyConverter implements Converter<RequestBody, RequestBody> {
static final RequestBodyConverter INSTANCE = new RequestBodyConverter();
@Override
public RequestBody convert(RequestBody value) {
//原封不動(dòng)返回
return value;
}
}
static final class StreamingResponseBodyConverter
implements Converter<ResponseBody, ResponseBody> {
static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();
@Override
public ResponseBody convert(ResponseBody value) {
return value;
}
}
static final class BufferingResponseBodyConverter
implements Converter<ResponseBody, ResponseBody> {
static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();
@Override
public ResponseBody convert(ResponseBody value) throws IOException {
try {
// Buffer the entire body to avoid future I/O.
return Utils.buffer(value);
} finally {
value.close();
}
}
}
/**
* 返回值的泛型是String
*/
static final class ToStringConverter implements Converter<Object, String> {
static final ToStringConverter INSTANCE = new ToStringConverter();
@Override
public String convert(Object value) {
return value.toString();
}
}
}
Call,發(fā)起請(qǐng)求
通過上面的步驟,解析API接口上的注解,查找CallAdapter和Converter,只是loadServiceMethod()的處理過程,然后返回ServiceMethod實(shí)例,再調(diào)用它的invoke()方法進(jìn)行調(diào)用,而ServiceMethod只是抽象類,具體實(shí)現(xiàn)在HttpServiceMethod
invoke(),返回一個(gè)Call實(shí)例,而它是一個(gè)接口,提供了一些請(qǐng)求方法,核心實(shí)現(xiàn)是OkHttpCall,還有一個(gè)ExecutorCallbackCall子類是做裝飾器作用的,主要把回調(diào)方法通過平臺(tái)的主線程調(diào)度器進(jìn)行轉(zhuǎn)發(fā),實(shí)現(xiàn)主線程回調(diào)
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
/**
* 執(zhí)行方法調(diào)用
*/
@Override
final @Nullable
ReturnT invoke(Object[] args) {
//創(chuàng)建Call實(shí)例
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
//進(jìn)行適配后返回結(jié)果
return adapt(call, args);
}
}
- Call接口
主要請(qǐng)求方法有2個(gè),execute同步請(qǐng)求,enqueue異步請(qǐng)求
/**
* 請(qǐng)求封裝,內(nèi)部封裝了OkHttp的Call
*/
public interface Call<T> extends Cloneable {
/**
* 同步請(qǐng)求
*/
Response<T> execute() throws IOException;
/**
* 異步請(qǐng)求
*
* @param callback 回調(diào)
*/
void enqueue(Callback<T> callback);
/**
* 是否已經(jīng)被執(zhí)行
*/
boolean isExecuted();
/**
* 取消請(qǐng)求
*/
void cancel();
/**
* 是否請(qǐng)求已經(jīng)被取消
*/
boolean isCanceled();
/**
* 克隆請(qǐng)求
*/
Call<T> clone();
/**
* 獲取請(qǐng)求的Request對(duì)象
*/
Request request();
/**
* 獲取請(qǐng)求的超時(shí)配置
*/
Timeout timeout();
}
- OkHttpCall
發(fā)現(xiàn),OkHttpCall是對(duì)OkHttp的一層封裝,做了一些響應(yīng)碼的處理,和Convert轉(zhuǎn)換器的調(diào)用,OkHttp的Call類是沒有數(shù)據(jù)轉(zhuǎn)換的,而Retrofit的Call類則是有Convert的支持,實(shí)現(xiàn)數(shù)據(jù)和模型的轉(zhuǎn)換
/**
* Call接口的實(shí)現(xiàn),使用OkHttp進(jìn)行請(qǐng)求,并進(jìn)行結(jié)果回調(diào)的封裝類,具有數(shù)據(jù)和模型的轉(zhuǎn)換能力
*/
final class OkHttpCall<T> implements Call<T> {
private final RequestFactory requestFactory;
private final Object[] args;
private final okhttp3.Call.Factory callFactory;
private final Converter<ResponseBody, T> responseConverter;
private volatile boolean canceled;
@GuardedBy("this")
private @Nullable
okhttp3.Call rawCall;
@GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
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;
}
@SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state.
@Override
public OkHttpCall<T> clone() {
return new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
}
@Override
public synchronized Request request() {
try {
return getRawCall().request();
} catch (IOException e) {
throw new RuntimeException("Unable to create request.", e);
}
}
@Override
public synchronized Timeout timeout() {
try {
return getRawCall().timeout();
} catch (IOException e) {
throw new RuntimeException("Unable to create call.", e);
}
}
/**
* 獲取真實(shí)請(qǐng)求的實(shí)例,就是OkHttp的Call
*/
@GuardedBy("this")
private okhttp3.Call getRawCall() throws IOException {
okhttp3.Call call = rawCall;
//已經(jīng)生成過了,直接返回
if (call != null) {
return call;
}
//不是第一次進(jìn)行接口請(qǐng)求,并且發(fā)生錯(cuò)誤,把錯(cuò)誤再次拋出
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
//創(chuàng)建OkHttp的Call對(duì)象
try {
return rawCall = createRawCall();
} catch (RuntimeException | Error | IOException e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
//調(diào)用了一次enqueue()異步請(qǐng)求,不能再次調(diào)用
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
//創(chuàng)建OkHttp的Call對(duì)象
if (call == null && failure == null) {
try {
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
//失敗了,回調(diào)外部
if (failure != null) {
callback.onFailure(this, failure);
return;
}
//取消了任務(wù),對(duì)真實(shí)請(qǐng)求做取消
if (canceled) {
call.cancel();
}
//發(fā)起異步請(qǐng)求
call.enqueue(new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
//執(zhí)行,并解析響應(yīng),統(tǒng)一返回Retrofit的Response對(duì)象
response = parseResponse(rawResponse);
} catch (Throwable e) {
//解析失敗,回調(diào)外部
throwIfFatal(e);
callFailure(e);
return;
}
//解析成功,回調(diào)外部
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) {
//請(qǐng)求失敗,回調(diào)外部
callFailure(e);
}
/**
* 回調(diào)失敗
*/
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}
@Override
public synchronized boolean isExecuted() {
return executed;
}
@Override
public Response<T> execute() throws IOException {
okhttp3.Call call;
//同步請(qǐng)求
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = getRawCall();
}
//如果被取消,則取消任務(wù)
if (canceled) {
call.cancel();
}
//執(zhí)行,并解析響應(yīng),統(tǒng)一返回Retrofit的Response對(duì)象
return parseResponse(call.execute());
}
/**
* 創(chuàng)建OkHttp3的Call對(duì)象
*/
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
//設(shè)置的OkHttpClient,不能返回null
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
/**
* 執(zhí)行,并解析響應(yīng),統(tǒng)一返回Retrofit的Response對(duì)象
*/
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
//移除真實(shí)請(qǐng)求的Body,方便傳遞
rawResponse = rawResponse
.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
//響應(yīng)碼不為正常的
if (code < 200 || code >= 300) {
try {
ResponseBody bufferedBody = Utils.buffer(rawBody);
//生成錯(cuò)誤的Response對(duì)象
return Response.error(bufferedBody, rawResponse);
} finally {
//關(guān)閉流
rawBody.close();
}
}
//204:請(qǐng)求成功了,但是沒有相應(yīng)體
//205:請(qǐng)求成功了,重置表單,一般WebView才有
if (code == 204 || code == 205) {
rawBody.close();
//由于沒有響應(yīng)體,直接返回成功
return Response.success(null, rawResponse);
}
//包裝一層,捕獲異常
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
//把ResponseBody轉(zhuǎn)換具體的泛型模型類
T body = responseConverter.convert(catchingBody);
//返回Response
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;
}
}
@Override
public void cancel() {
canceled = true;
okhttp3.Call call;
synchronized (this) {
call = rawCall;
}
//取消任務(wù)
if (call != null) {
call.cancel();
}
}
@Override
public boolean isCanceled() {
if (canceled) {
return true;
}
synchronized (this) {
return rawCall != null && rawCall.isCanceled();
}
}
static final class NoContentResponseBody extends ResponseBody {
private final @Nullable
MediaType contentType;
private final long contentLength;
NoContentResponseBody(@Nullable MediaType contentType, long contentLength) {
this.contentType = contentType;
this.contentLength = contentLength;
}
@Override
public MediaType contentType() {
return contentType;
}
@Override
public long contentLength() {
return contentLength;
}
@Override
public BufferedSource source() {
throw new IllegalStateException("Cannot read raw response body of a converted body.");
}
}
/**
* 裝飾器,捕獲異常的ResponseBody
*/
static final class ExceptionCatchingResponseBody extends ResponseBody {
private final ResponseBody delegate;
private final BufferedSource delegateSource;
@Nullable
IOException thrownException;
ExceptionCatchingResponseBody(ResponseBody delegate) {
this.delegate = delegate;
this.delegateSource = Okio.buffer(
new ForwardingSource(delegate.source()) {
@Override
public long read(Buffer sink, long byteCount) throws IOException {
try {
return super.read(sink, byteCount);
} catch (IOException e) {
thrownException = e;
throw e;
}
}
});
}
@Override
public MediaType contentType() {
return delegate.contentType();
}
@Override
public long contentLength() {
return delegate.contentLength();
}
@Override
public BufferedSource source() {
return delegateSource;
}
@Override
public void close() {
delegate.close();
}
void throwIfCaught() throws IOException {
if (thrownException != null) {
throw thrownException;
}
}
}
}
Gson轉(zhuǎn)換器
Converter轉(zhuǎn)換器主要是做2種事情
- Json上傳類型的請(qǐng)求時(shí),模型轉(zhuǎn)Json
- 接口響應(yīng)時(shí),Json轉(zhuǎn)模型
而Gson就擁有這樣的能力,所以Retrofit也提供Gson的轉(zhuǎn)換器工廠,GsonConverterFactory
簡單使用
在Retrofit.Builder構(gòu)建時(shí),通過addConverterFactory,添加GsonConverterFactory轉(zhuǎn)換器
//創(chuàng)建Retrofit實(shí)例
Retrofit retrofit = new Retrofit.Builder()
//配置OkHttpClient
.callFactory(new OkHttpClient.Builder().build())
//配置基礎(chǔ)Url
.baseUrl("https://www.wanandroid.com")
//Gson轉(zhuǎn)換器
.addConverterFactory(GsonConverterFactory.create())
//開始創(chuàng)建
.build();
- 添加一個(gè)請(qǐng)求方法,可以直接寫模型的泛型
public interface WanAndroid {
/**
* Retrofit Call,獲取首頁文章列表,如果不添加轉(zhuǎn)換器,則泛型只能是ResponseBody
*/
@GET("article/list/{page}/json")
Call<ResponseBody> getHomeArticleByCall(@Path("page") int page);
/**
* 添加了轉(zhuǎn)換器,則可以直接用模型類的泛型,不需要ResponseBody了
*/
@GET("article/list/{page}/json")
Call<HttpModel<PageModel<HomeArticleModel>>> getHomeArticleByCallWithConverter(
@Path("page") int page
);
}
- 調(diào)用,不需要自己做Json和模型的轉(zhuǎn)換,優(yōu)雅了許多
wanAndroid.getHomeArticleByCallWithConverter(page).enqueue(new Callback<HttpModel<PageModel<HomeArticleModel>>>() {
@Override
public void onResponse(Call<HttpModel<PageModel<HomeArticleModel>>> call,
Response<HttpModel<PageModel<HomeArticleModel>>> response) {
//請(qǐng)求成功
}
@Override
public void onFailure(Call<HttpModel<PageModel<HomeArticleModel>>> call, Throwable throwable) {
//請(qǐng)求失敗
}
});
源碼分析
- 轉(zhuǎn)換器工廠,實(shí)現(xiàn)Converter.Factory接口
/**
* Gson轉(zhuǎn)換器工廠
*/
public final class GsonConverterFactory extends Converter.Factory {
/**
* 創(chuàng)建方法,使用默認(rèn)構(gòu)造方法的Gson實(shí)例,JSON解碼使用UTF-8
*/
public static GsonConverterFactory create() {
return create(new Gson());
}
/**
* 指定Gson實(shí)例進(jìn)行創(chuàng)建
*/
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
//ResponseBody響應(yīng)數(shù)據(jù)轉(zhuǎn)模型
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) {
//Json請(qǐng)求方式時(shí),模型轉(zhuǎn)Json
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}
- GsonRequestBodyConverter,Json請(qǐng)求方式時(shí),模型轉(zhuǎn)Json的轉(zhuǎn)換器
/**
* Json請(qǐng)求方式時(shí),模型轉(zhuǎn)Json的轉(zhuǎn)換器
*/
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());
}
}
- GsonResponseBodyConverter,ResponseBody響應(yīng)數(shù)據(jù)轉(zhuǎn)模型的轉(zhuǎn)換器
/**
* ResponseBody響應(yīng)數(shù)據(jù)轉(zhuǎn)模型的轉(zhuǎn)換器
*/
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();
}
}
}
總結(jié)
Retrofit中,使用了很多設(shè)計(jì)模式,例如:
- 創(chuàng)建實(shí)例時(shí)使用Builder構(gòu)建者模式,配置更加靈活
- 代理模式,主要是JDK動(dòng)態(tài)代理,讓我們可以用接口,實(shí)現(xiàn)聲明式Http請(qǐng)求調(diào)用
- 責(zé)任鏈模式,配置多個(gè)CallAdapter和Converter,查找到最終匹配當(dāng)前調(diào)用的方法的返回值,和Json和模型之間轉(zhuǎn)換
- 策略模式,不同平臺(tái)的主線程執(zhí)行器實(shí)現(xiàn),通過Platform類拓展不同平臺(tái)的子類
- 裝飾器模式,ExecutorCallbackCall,實(shí)現(xiàn)Call接口,對(duì)同樣實(shí)現(xiàn)了Call接口的OkHttpCall進(jìn)行裝飾,實(shí)現(xiàn)enqueue()異步請(qǐng)求的回調(diào)在主線程中回調(diào)
既然Retrofit可以兼容多平臺(tái),而鴻蒙系統(tǒng),也是基于Java,同樣有主線程API,我們是不是可以拓展Retrofit的Platform類,實(shí)現(xiàn)鴻蒙上的子線程請(qǐng)求,主線程回調(diào)呢~