前言
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.reibang.com/")
//設(shè)置轉(zhuǎn)換工廠
.addConverterFactory(GsonConverterFactory.create())
//設(shè)置適配器
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
這里之所以叫Retrofit客戶端。客戶端提供的子系統(tǒng)有:
1.serviceMethodCache(自定義的接口映射對象集合)
2.baseUrl(請求地址)
3.callFactory(默認(rèn)為OkHttpCall)
4.converterFactories(數(shù)據(jù)解析器工廠集合)
5.callAdapterFactories(Call適配器工廠集合)
6.callbackExecutor(回調(diào)執(zhí)行钱豁,android平臺默認(rèn)為MainThreadExecutor)
關(guān)于Retrofit客戶端的創(chuàng)建
客戶端的創(chuàng)建有兩種方式:
第一種就是使用構(gòu)造函數(shù)棉钧,如下所示。
第二種就是Retrofit.Builder()挺益。
我們一般使用第二種方式來創(chuàng)建客戶端歉糜。
public final class Retrofit {
//對網(wǎng)絡(luò)請求接口中方法注解進(jìn)行解析后得到的對象,緩存到map中
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
//網(wǎng)絡(luò)請求器工廠
final okhttp3.Call.Factory callFactory;
//網(wǎng)絡(luò)請求適配器器工廠集合
final List<CallAdapter.Factory> callAdapterFactories;
//數(shù)據(jù)轉(zhuǎn)換器工廠集合
final List<Converter.Factory> converterFactories;
//回調(diào)方法執(zhí)行器
final @Nullable Executor callbackExecutor;
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;
}
}
接下來看看通過構(gòu)建者模式創(chuàng)造的Retrofit客戶端望众,使用構(gòu)建者模式匪补,有如下好處伞辛,對外可以屏蔽創(chuàng)建對象的細(xì)節(jié),同時也可以自由配置Retrofit客戶端的屬性夯缺。
public static final class Builder {
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;
public Builder() {
this(Platform.get());
}
接著就到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) {
//安卓平臺的platform
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
接著看看這個安卓平臺的做了啥事
static class Android extends Platform {
@IgnoreJRERequirement // Guarded by API check.
@Override boolean isDefaultMethod(Method method) {
if (Build.VERSION.SDK_INT < 24) {
return false;
}
return method.isDefault();
}
@Override public Executor defaultCallbackExecutor() {
//返回一個默認(rèn)的回調(diào)方法執(zhí)行器始锚,子線程請求后的數(shù)據(jù)通過這個來返回到主線程
return new MainThreadExecutor();
}
//默認(rèn)的網(wǎng)絡(luò)請求適配器工廠是ExecutorCallAdapterFactory ,常用的還有
//RxjavaCallAdapter喳逛,callAdapterFactory
@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
return Build.VERSION.SDK_INT >= 24
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
@Override int defaultCallAdapterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 2 : 1;
}
//默認(rèn)的轉(zhuǎn)換器瞧捌,常用的有GsonConverterFactory
@Override List<? extends Converter.Factory> defaultConverterFactories() {
return Build.VERSION.SDK_INT >= 24
? singletonList(OptionalConverterFactory.INSTANCE)
: Collections.<Converter.Factory>emptyList();
}
@Override int defaultConverterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 1 : 0;
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
可以看出這個Build類初始化了如下:
Platform:安卓平臺對象
網(wǎng)絡(luò)請求適配器工廠:CallAdapterFactory
數(shù)據(jù)轉(zhuǎn)換器工廠:converterFactory
回調(diào)執(zhí)行器:callbackExecutor
初始化數(shù)據(jù)轉(zhuǎn)換器
addConverterFactory(GsonConverterFactory.creat())
先看看GsonConverterFactory.creat()里做了啥事
public final class GsonConverterFactory extends Converter.Factory {
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;
}
//在自定義數(shù)據(jù)轉(zhuǎn)化器時需重寫這兩個方法
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}
這就是創(chuàng)建了一個還有Gson對象的GsonConverterFactory,并添加進(jìn)converterFactorues中
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
由此看出
1.Retrofit默認(rèn)使用Gson進(jìn)行解析
2.若使用其他解析方式(如XML或Protocobuf)润文,也可通過自定義數(shù)據(jù)解析器來實現(xiàn)(必須繼承 Converter.Factory)姐呐,重寫那兩個方法。
還有最后一個步驟典蝌,build(),Retrofit客戶端就創(chuàng)建完成了曙砂。
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//配置回調(diào)方法執(zhí)行器
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 配置網(wǎng)絡(luò)請求適配器工廠
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// 配置數(shù)據(jù)轉(zhuǎn)換器工廠
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);
}
}
創(chuàng)建網(wǎng)絡(luò)請求接口的實例
public interface Service{
@GET("wanandroid")
Call<Bean> getCall();
}
//使用了外觀模式,通過傳入class可以對每一個網(wǎng)絡(luò)請求接口的訪問
Service service = retrofit.create(Service.class);
Call<Bean> call = service.getCall();
Retrofit是通過動態(tài)代理模式創(chuàng)建網(wǎng)絡(luò)接口的實例骏掀,同時鸠澈,通過解析注解("wanandroid")進(jìn)行了網(wǎng)絡(luò)請求參數(shù)的配置
現(xiàn)在先來看接口的實例如何創(chuàng)建出來的
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() {
//這就是配置了那個數(shù)據(jù)轉(zhuǎn)換器和網(wǎng)絡(luò)適配器和回調(diào)池的platform
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);
}
});
}
接著看loadServiceMethod()里做了啥事
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;
}
接著去看parseAnnotations里做了啥事
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//這個就是去解析一些請求參數(shù)截驮,比如說是否有請求體笑陈,請求方法是get post等等
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.");
}
//這里就是去解析注解信息帶參數(shù)path的
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
最后就生成了一個serviceMethod對象。
接下來去分析一下這個serviceMethod
final class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
//解析參數(shù)
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
Type responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
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;
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
//去遍歷網(wǎng)絡(luò)請求適配工廠
// //網(wǎng)絡(luò)接口方法的返回值類型來確定合適的CallAdapter實例
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method) {
Type returnType = method.getGenericReturnType();
Annotation[] annotations = method.getAnnotations();
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);
}
}
//去遍歷數(shù)據(jù)轉(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);
}
}
private final RequestFactory requestFactory;
private final okhttp3.Call.Factory callFactory;
private final CallAdapter<ResponseT, ReturnT> callAdapter;
private final Converter<ResponseBody, ResponseT> responseConverter;
private HttpServiceMethod(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
CallAdapter<ResponseT, ReturnT> callAdapter,
Converter<ResponseBody, ResponseT> responseConverter) {
this.requestFactory = requestFactory;
this.callFactory = callFactory;
this.callAdapter = callAdapter;
this.responseConverter = responseConverter;
}
//重點在這葵袭,生成serviceMethod對象時涵妥,會調(diào)用到invoke方法
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
}
我們知道,Retrofit是對OkHttp做了一層封裝坡锡,具體的網(wǎng)絡(luò)發(fā)起人還是OkHttp蓬网,關(guān)鍵是怎么樣通過這個serviceMethod來完成的呢?
先來看看構(gòu)造函數(shù)鹉勒,接收四個帆锋,第一個就是請求工廠,包含所有的請求參數(shù)禽额,第二個就是網(wǎng)絡(luò)接口的參數(shù)锯厢,第三個就是網(wǎng)絡(luò)接口轉(zhuǎn)換工廠,第四個就是數(shù)據(jù)轉(zhuǎn)化工廠绵疲。
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;
}
這里已經(jīng)可以獲取到我們所有網(wǎng)絡(luò)請求發(fā)起需要的參數(shù)了哲鸳。
接著去看看adapt,這就是網(wǎng)絡(luò)接口請求返回類型的的適配,比如用的時RxjavaCallAdapter盔憨,返回的就是observerble徙菠。
網(wǎng)絡(luò)請求的發(fā)起
最后的請求由OkhttpCall來發(fā)起。
public void enqueue(final Callback<T> callback) {
okhttp3.Call call;
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;
}
}
這個callBack就是在創(chuàng)建時客戶端時那個ExtutorCallback郁岩。來完成線程的切換
總結(jié)
1.Retrofit將Http請求抽象成java接口
2.接口里用注解 描述和配置網(wǎng)絡(luò)請求參數(shù)
3.動態(tài)代理的方式來生成call對象婿奔。