Retrofit,中文的翻譯爲「式樣翻新」的意思,是一個基於OKHttp的RESTful網絡請求框架。通俗一點來講,Retrofit就是一個網絡請求框架的封裝。一樣是由Square公司開源的Android熱門網絡框架之一,其具備功能強大、簡潔易用及高可拓展性特色。java
官網網址:Retrofit官網git
Github地址:Githubgithub
一、基於OkHttp並遵循Restful API設計風格json
二、經過註解的形式,可簡便的配置網絡請求參數設計模式
三、支持同步及異步的網絡請求方式緩存
四、支持RxJavabash
五、支持多種數據格式的解析(Json、XML、Protobuf等)微信
一、gradle引入庫網絡
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0' //配置使用Gson解析響應數據 可選
implementation 'com.squareup.retrofit2:adapter-rxjava:2.4.0' //配置支持RxJava 可選
複製代碼
二、初始化Retrofit對象app
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL) //配置baseUrl
.addConverterFactory(GsonConverterFactory.create()) //配置使用Gson解析響應數據
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) //配置支持RxJava
.build();
複製代碼
public interface WeatherService {
//使用GET請求 直接返回原始數據
@GET("weather?location=%E5%98%89%E5%85%B4&output=json&ak=5slgyqGDENN7Sy7pw29IUvrZ")
Call<ResponseBody> cityNameQueryWeather();
//使用GET請求 返回Json映射對象
@GET("{weather}?location=%E5%98%89%E5%85%B4&output=json")
Call<WeatherResp> cityWeatherPath(@Path("weather") String weather, @Query("ak") String ak);
//使用POST請求 支持RxJava返回
@FormUrlEncoded()
@POST("{weather}")
rx.Observable<WeatherResp> cityWeatherPost(@Path("weather") String weather, @Field("ak") String ak, @Field("location") String location, @Field("output") String output);
}
複製代碼
WeatherService weatherService = retrofit.create(WeatherService.class);
Call<ResponseBody> responseBodyCall = weatherService.cityNameQueryWeather();
try {
Response<ResponseBody> responseBody = responseBodyCall.execute();
System.out.println("call:" + responseBody.body().string());
} catch (IOException e) {
e.printStackTrace();
}
複製代碼
WeatherService weatherService = retrofit.create(WeatherService.class);
Call<WeatherResp> responseBodyCall = weatherService.cityWeatherPath("weather", "5slgyqGDENN7Sy7pw29IUvrZ");
responseBodyCall.enqueue(new Callback<WeatherResp>() {
@Override
public void onResponse(Call<WeatherResp> call, Response<WeatherResp> response) {
System.out.println("call:" + response.toString());
}
@Override
public void onFailure(Call<WeatherResp> call, Throwable t) {
}
});
複製代碼
WeatherService weatherService = retrofit.create(WeatherService.class);
weatherService.rxCityWeatherPost("weather", "5slgyqGDENN7Sy7pw29IUvrZ", "%E5%98%89%E5%85%B4", "json")
.subscribeOn(Schedulers.io()) //在新線程裏面處理網絡請求
.observeOn(AndroidSchedulers.mainThread()) //在主線程裏面接受返回的數據
.subscribe(new rx.Observer<WeatherResp>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(WeatherResp weatherResp) {
System.out.println("call:" + weatherResp.toString());
}
});
複製代碼
詳細的Retrofit的註解配置及各註解的使用,推薦參考
這是一份很詳細的 Retrofit 2.0 使用教程(含實例講解)
類 | 功能說明 |
---|---|
Retrofit | 裏面包含了不少對象,serviceMethodCache(自定義的接口映射對象集合)、baseUrl(請求地址)、callFactory(默認爲OKHttpCall)、converterFactories(數據解析器工廠集合)、callAdapterFactories(Call適配器工廠集合)、callbackExecutor(回調執行,Android平臺默認爲MainThreadExecutor)使用Builder模型構建 |
Platform | Retrofit中用來管理多平臺的方法,支持Android、Java8。經過findPlatform獲取對應的平臺,同時也初始化了defaultCallAdapterFactory工廠 |
ServiceMethod | 接口映射的網絡請求對象,經過動態代理,將自定義接口的標註轉換爲該對象,將標註及參數生成OkHttp所需的Request對象。Retrofit的create經過動態代理攔截,將每個自定義接口轉換成爲一個ServiceMethod對象,並經過經過serviceMethodCache進行緩存。 |
Call | Retrofit定義的網絡請求接口,包含execute、enqueue等方法 |
OkHttpCall | Ohttp的Call實現,經過createRawCall獲得真正的 okhttp3.Call對象,用於進行實際的網絡請求 |
CallAdapter.Factory | CallAdapter的靜態工廠,包含get的抽象方法,用於生產CallAdapter對象 |
ExecutorCallAdapterFactory | Android平臺默認的CallAdapter工廠,get方法使用匿名內部類實現CallAdapter,返回ExecutorCallbackCall,實現了Call |
ExecutorCallbackCall | 採用靜態代理設計,delegate實際爲OkHttpCall,使用callbackExecutor實現回調在主線程中執行 |
RxJavaCallAdapterFactory | Rxjava平臺的CallAdapter工廠,get方法返回RxJavaCallAdapter對象 |
RxJavaCallAdapter | Rxjava平臺的設配器,返回observable對象 |
Converter.Factory | 數據解析器工廠,用於生產Converter實例 |
GsonConverterFactory | 數據解析工廠實例,返回了GsonResponseBodyConverter數據解析器 |
GsonResponseBodyConverter | Gson的數據解析器,將服務端返回的json對象轉換成對應的java模型 |
Response | Retrofit網絡請求響應的Response |
咱們都知道,Retrofit經過自定義interface及相關的標註來描述一個http的請求,使用很是簡便,且易於維護。
這是Retrofit設計的精髓之一,,當調用Retrofit的create()方法時,會進行動態代理監聽。當執行具體的接口方法時,會回調InvocationHandler。經過反射解析method的標註及參數,生成ServiceMethod對象,ServiceMethod中封裝了OKHttp網絡請求所需的相關參數。
源碼實現以下:
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();
@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);
}
//生成ServiceMethod
ServiceMethod<Object, Object> serviceMethod =o
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
複製代碼
經過源碼咱們知道,具體的轉換方法爲 (ServiceMethod<Object, Object>) loadServiceMethod(method),具體的實現以下:
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
複製代碼
經過Builder構建模式,建立一個ServiceMethod對象,並加入緩存,具體的構造實現以下:
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
if (!hasBody) {
if (isMultipart) {
throw methodError(
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError("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; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}
return new ServiceMethod<>(this);
}
複製代碼
build()方法會經過反射去解析method的標註、參數的類型等。詳細的解析可參考源碼ParameterHandler相關實現,這裏主要對流程進行剖析。
總結一下,Retrofit經過自定義interface及相關的標註來描述一個http的請求,當調用Retrofit的create()方法時,會進行動態代理監聽。當執行具體的接口方法時,會回調InvocationHandler。經過反射解析method的標註及參數,生成ServiceMethod對象,ServiceMethod中封裝了OKHttp網絡請求所需的相關參數。這就是Retrofit將定義的interface轉換成網絡請求對象的過程。
Retrofit支持多種數據解析方式,使用時須要在Gradle添加依賴。
數據解析器 | Gradle依賴 |
---|---|
Gson | com.squareup.retrofit2:converter-gson:2.4.0 |
Jackson | com.squareup.retrofit2:converter-jackson:2.4.0 |
Simple XML | com.squareup.retrofit2:converter-simplexml:2.4.0 |
Protobuf | com.squareup.retrofit2:converter-protobuf:2.4.0 |
Moshi | com.squareup.retrofit2:converter-moshi:2.4.0 |
Wire | com.squareup.retrofit2:converter-wire:2.4.0 |
Scalars | com.squareup.retrofit2:converter-scalars:2.4.0 |
首先在Retrofit的初始化添加Converter,addConverterFactory(GsonConverterFactory.create())。具體實現以下:
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
複製代碼
將Converter的工廠加入到converterFactories集合中。
經過上述的流程分析,咱們知道Retrofit當網絡請求成功後會執行,OkHttpCall中的parseResponse方法。
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
// Remove the body's source (the only stateful object) so we can pass the response along. rawResponse = rawResponse.newBuilder() .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength())) .build(); int code = rawResponse.code(); if (code < 200 || code >= 300) { try { // Buffer the entire body to avoid future I/O. ResponseBody bufferedBody = Utils.buffer(rawBody); return Response.error(bufferedBody, rawResponse); } finally { rawBody.close(); } } if (code == 204 || code == 205) { rawBody.close(); return Response.success(null, rawResponse); } ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody); try { T body = serviceMethod.toResponse(catchingBody); return Response.success(body, rawResponse); } catch (RuntimeException e) { // If the underlying source threw an exception, propagate that rather than indicating it was // a runtime exception. catchingBody.throwIfCaught(); throw e; } } 複製代碼
其中關鍵的代碼爲 T body = serviceMethod.toResponse(catchingBody),具體實現以下:
/** Builds a method return value from an HTTP response body. */
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
複製代碼
這裏就是 Converter實現轉換的地方,那麼responseConverter在哪裏進行初始化呢?在ServiceMethod的Build方法中,會調用createResponseConverter()進行數據解析器的建立,實現以下:
private Converter<ResponseBody, T> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create converter for %s", responseType);
}
}
複製代碼
調用了 retrofit.responseBodyConverter方法
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
複製代碼
調用了 retrofit.nextResponseBodyConverter方法
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
int start = converterFactories.indexOf(skipPast) + 1;
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());
}
複製代碼
經過Retrofit的converterFactories工廠集合匹配獲取開始添加的數據轉換工廠
經過Retrofit build() 中發現以下代碼,converterFactories.add(new BuiltInConverters()),可知Retrofit默認的數據轉換器工廠爲BuiltInConverters。主要實現以下:
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
複製代碼
會將數據轉換爲ResponseBody對象,因此若是Retrofit默認不使用任何數據解析器,定義interface方法時接收數據對象使用 Call。
Retrofit支持多種網絡請求適配器方式:guava、Java8和rxjava 。Android默認的適配器工廠爲ExecutorCallAdapterFactory,最後的回調經過ExecutorCallbackCall切換至主線程運行。
網絡請求適配器 | Gradle依賴 |
---|---|
guava | com.squareup.retrofit2:adapter-guava:2.4.0 |
Java8 | com.squareup.retrofit2:adapter-java8:2.4.0 |
rxjava | com.squareup.retrofit2:adapter-rxjava:2.4.0 |
首先在Retrofit的初始化添加CallAdapter工廠,addCallAdapterFactory(RxJavaCallAdapterFactory.create())。具體實現以下:
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
複製代碼
將CallAdapter的工廠加入到callAdapterFactories集合中。
經過上述Retrofit的create方法中分析可知,當攔截到interface的方法調用後最後會執行 return serviceMethod.adapt(okHttpCall)。adapt的實現以下:
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
複製代碼
就是在這個地方觸發了callAdapter的adapt方法。返回最終適配的具體對象。
Android平臺默認的CallAdapter工廠爲ExecutorCallAdapterFactory。經過Retrofit的build()方法可知:
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
複製代碼
platform.defaultCallAdapterFactory的實現以下:
CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor != null) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
return DefaultCallAdapterFactory.INSTANCE;
}
複製代碼
ExecutorCallAdapterFactory的CallAdapter建立以下:
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
} else {
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
public Type responseType() {
return responseType;
}
public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallAdapterFactory.ExecutorCallbackCall(ExecutorCallAdapterFactory.this.callbackExecutor, call);
}
};
}
}
複製代碼
adapt方法最後返回仍是Call對象,具體的適配實現由ExecutorCallbackCall執行,具體源碼以下:
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;
}
public void enqueue(final Callback<T> callback) {
Utils.checkNotNull(callback, "callback == null");
this.delegate.enqueue(new Callback<T>() {
public void onResponse(Call<T> call, final Response<T> response) {
ExecutorCallbackCall.this.callbackExecutor.execute(new Runnable() {
public void run() {
if (ExecutorCallbackCall.this.delegate.isCanceled()) {
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
public void onFailure(Call<T> call, final Throwable t) {
ExecutorCallbackCall.this.callbackExecutor.execute(new Runnable() {
public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
public Response<T> execute() throws IOException {
return this.delegate.execute();
}
}
複製代碼
具體的執行仍是經過delegate(OkHttpCall)來執行,可是在回調使用了 ExecutorCallbackCall.this.callbackExecutor.execute()方法,Android平臺的callbackExecutor實現爲MainThreadExecutor。具體源碼以下:
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
複製代碼
因此ExecutorCallAdapterFactory中適配最後的設配對象仍是Call,實現仍是OkHttpCall,經過 MainThreadExecutor,將回調切換在UI線程中運行
在ServiceMethod的Build方法中,createCallAdapter()進行適配器的的建立,實現以下:
private CallAdapter<T, R> createCallAdapter() {
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
複製代碼
調用了 retrofit.callAdapter
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
複製代碼
調用了 retrofit.nextCallAdapter
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
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());
}
複製代碼
經過Retrofit的callAdapterFactories工廠集合匹配獲取開始添加的適配器工廠
一、須要定義一個工廠類繼承Converter.Factory
二、複寫responseBodyConverter及requestBodyConverter方法
三、在Retrofit定義時加入自定義的Converter,addConverterFactory(new CustomConverterFactory())
/**
* @author allen
* @date 2018/8/7
* 返回服務端返回的string結果
*/
public class CustomConverterFactory extends Converter.Factory {
@Nullable
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return StringResponseBodyConverter.INSTANCE;
}
@Nullable
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return StringRequestBodyConverter.INSTANCE;
}
static final class StringResponseBodyConverter implements Converter<ResponseBody, String> {
static final CustomConverterFactory.StringResponseBodyConverter INSTANCE = new CustomConverterFactory.StringResponseBodyConverter();
@Override
public String convert(ResponseBody value) {
try {
System.out.println("CustomConverterFactory");
return value.string();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
}
static final class StringRequestBodyConverter implements Converter<RequestBody, RequestBody> {
static final CustomConverterFactory.StringRequestBodyConverter INSTANCE = new CustomConverterFactory.StringRequestBodyConverter();
@Override
public RequestBody convert(@NonNull RequestBody value) {
return value;
}
}
}
複製代碼
一、須要定義一個工廠類繼承CallAdapter.Factory
二、複寫CallAdapter get方法
三、在Retrofit定義時加入自定義的CallAdapter, addCallAdapterFactory(new CustomCallAdapterFactory())
/**
* @author allen
* @date 2018/8/7
*/
public class CustomCallAdapterFactory extends CallAdapter.Factory {
@Nullable
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
return new CallAdapter<Object, Object>() {
@Override
public Type responseType() {
return String.class;
}
@Override
public Object adapt(Call<Object> call) {
System.out.println("CustomCallAdapterFactory adapt(");
return call;
}
};
}
}
複製代碼
一、建造者模式
Retrofit對象的建立、ServiceMethod對象建立都使用Build模式,將複雜對象的建立和表示分離,調用者不須要知道複雜的建立過程,使用Build的相關方法進行配置建立對象。
二、外觀模式
Retrofit對外提供了統一的調度,屏蔽了內部的實現,使得使用該網絡庫簡單便捷。
三、動態代理模式
經過動態代理的方式,當調用Retrofit的create()方法時,會進行動態代理監聽。當執行具體的接口方法時,會回調InvocationHandler。經過反射解析method的標註及參數,生成ServiceMethod對象。
四、靜態代理模式 Android平臺默認的適配器ExecutorCallbackCall,採用靜態代理的模式。具體的實現delegate爲OkHttpCall。
五、工廠模式 Converter及CallAdapter的建立都採用了工廠模式進行建立。
六、適配器模式 CallAdapter的adapt採用了適配器模式,使得interface的返回對象能夠動態擴展,加強了靈活性
大多數流行的開源框架都是通過頂級coder的設計,包含了不少精妙的設計。多學習分析,收益良多。
這是一份很詳細的 Retrofit 2.0 使用教程(含實例講解)
Android:手把手帶你深刻剖析 Retrofit 2.0 源碼
歡迎關注個人我的公衆號
微信搜索:一碼一浮生,或者搜索公衆號ID:life2code