1.使用者的retrofit建立
/**
* 初始化Retrofit
*/
public static void init() {
okHttpClient = HttpsUtils.getOKHttpClient();
//設定Retrofit
Retrofit client = new Retrofit.Builder()
.baseUrl(HOST)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build();
//建立業務請求物件
api = client.create(RequestApi.class);
}
複製程式碼
2. Retrofit:build()方法組裝資料以及新增適配和轉化器
public Retrofit build() {
//校驗baseUrl
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//獲取回撥工廠,預設使用okhttp
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//新增執行緒池
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 呼叫相關的介面卡
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// 執行相關的轉換器
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
複製程式碼
buid方法主要是構建一個真正的retrofit物件,載入介面卡,轉化器,callbackExecutor執行緒池,baseUrl等基本資料
3.建立的入口(Retrofit create())
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() {
//獲取對應的支援的平臺 android java
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, 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<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
複製程式碼
動態代理的核心方法,都會呼叫invoke,前面會加一些方法校驗,而且retrofit同樣支援android和java,所以也對平臺做了封裝,同時也加map快取對應的代理物件
4.loadServiceMethod載入服務方法
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
//加一個非同步鎖
synchronized (serviceMethodCache) {
//從的map中去拿
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
複製程式碼
加了一個同步鎖,防止多執行緒的資料混亂問題,map快取增加執行速度,構建之後同樣加入map中去
5.檢視ServiceMethod物件的建立方法Builder
public ServiceMethod build() {
//構建響應Call的介面卡,可以使用者通過addCallAdapterFactory() 工廠類新增
callAdapter = createCallAdapter();
//.....響應介面卡的返回型別校驗
// 建立響應的Converter變換器 可通過addConverterFactory 工廠類新增
responseConverter = createResponseConverter();
//一系列的請求註解校驗,具體看原始碼
return new ServiceMethod<>(this);
}
複製程式碼
構建響應的介面卡和轉換器,這些都可以被使用者通過工廠類從外部傳進來
6. Retrofit nextCallAdapter() 建立介面卡
ServiceMethod類:
private CallAdapter<T, R> createCallAdapter() {
//獲取介面指定的返回型別,Call或者是Observatble
Type returnType = method.getGenericReturnType();
//省略部分校驗
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);
}
public CallAdapter<?, ?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = adapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
//省略
}
複製程式碼
createCallAdapter校驗返回值型別 之後會回撥Retrofit的callAdapter方法之後執行介面卡list中的介面卡get方法
7.ExecutorCallAdapterFactory的get方法,之後呼叫執行緒池的建立方法
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
//建立執行緒池
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
複製程式碼
8.call.enqueue(new Callback)開始真正請求資料,呼叫ExecutorCallbackCall的enqueue方法
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) {
if (callback == null) throw new NullPointerException("callback == null");
呼叫okhtt.Call方法裡面的enqueue
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
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(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
//省略
}
複製程式碼
進入了okhttp的請求中
9.把子執行緒請求的資料回撥給主執行緒
這裡感覺比較巧妙,基本都是使用handler,在Platform類中定義android平臺時可以看到如下一段程式碼剛好和上面的ExecutorCallbackCall代理類delegate.enqueue(new Callback())呼應
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
//執行execute用handler的post方法到主執行緒
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
複製程式碼
利用主執行緒的handler的post方法在執行execute的時候把資料返回主執行緒
最後加上流程圖