因爲以前項目搭建的是 MVP 架構,由RxJava + Glide + OKHttp + Retrofit
等開源框架組合而成,以前也都是停留在使用層面上,沒有深刻的研究,最近打算把它們所有攻下,尚未關注的同窗能夠先關注一波,看完這個系列文章,(不論是面試仍是工做中處理問題)相信你都在知道原理的狀況下,處理問題更加駕輕就熟。html
Android 圖片加載框架 Glide 4.9.0 (一) 從源碼的角度分析 Glide 執行流程java
Android 圖片加載框架 Glide 4.9.0 (二) 從源碼的角度分析 Glide 緩存策略android
從源碼的角度分析 Rxjava2 的基本執行流程、線程切換原理git
從源碼的角度分析 OKHttp3 (一) 同步、異步執行流程github
從源碼的角度分析 OKHttp3 (二) 攔截器的魅力web
從源碼的角度分析 Retrofit 網絡請求,包含 RxJava + Retrofit + OKhttp 網絡請求執行流程json
Retrofit 跟以前介紹的 OKHttp
都是來自 Square
公司開源的項目,Retrofit
跟 OKHttp
也都屬於 HTTP
網絡請求框架,既然都是屬於網絡框架爲何咱們都要分析它呢?有使用過 Retrofit
框架的知道,它的底層其實就是基於 OKHttp 來進行網絡訪問的。按照嚴格來講我我的認爲 Retrofit 是基於 OKHttp 二次封裝,目的就是爲了使用更加簡單明瞭。設計模式
下面咱們就簡單以一個網絡請求來舉例說明一下,本章重點在於分析 Retrofit 源碼,因此若是對使用有不清楚的能夠看Retrofit API ,下面就以鴻洋大神 wanandroid 的開放 API :wanandroid.com/wxarticle/c… 來進行網絡請求:api
定義 Retrofit 網絡請求接口
public interface APIService {
//按照 Retrofit 要求定義接口 Retrofit + OKHttp 網絡訪問
@GET("/wxarticle/chapters/json")
Call<JsonObject> getWXarticle();
//按照 Retrofit 要求定義接口 RxJava + Retrofit + OKHttp 網絡訪問
@GET("/wxarticle/chapters/json")
Observable<JsonObject> getWXarticle();
}
複製代碼
初始化 Retrofit 實例
public static final String API_URL = "https://wanandroid.com";
//1. 配置 OKHttpClient 添加查看 Request / Response 數據攔截器
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
//打印請求前的請求數據
Request request = chain.request();
Log.d(TAG, request.toString());
//打印服務端響應數據
Response response = chain.proceed(request);
MediaType mediaType = response.body().contentType();
String content = response.body().string();
Log.d("JSON:", content);
Log.d("MediaType:", mediaType.toString());
return response.newBuilder().
body(ResponseBody.create(mediaType, content)).
build();
}
}).build();
//2. 構建 Retrofit 對象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL) //http API
.addConverterFactory(GsonConverterFactory.create()) //配置 GSON 轉換
.addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync()) //配置 RxJava ,支持異步訪問 create 同步
.client(okHttpClient)//主動配置 OKhttpClient
.build();
//3. 拿到 Retrofit 請求對象
APIService api = retrofit.create(APIService.class);
複製代碼
Retrofit + OKHttp
Call<JsonObject> call = api.getWXarticles();
//OKHttp 異步訪問網絡
call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, retrofit2.Response<JsonObject> response) {
Log.d(TAG, "Retrofit + OKHttp "+response.body().toString());
}
@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.d(TAG, "Retrofit + OKHttp "+t.getMessage());
}
});
複製代碼
RxJava + Retrofit + OKHttp
Observable<JsonObject> observable = api.getWXarticle();
observable.subscribeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<JsonObject>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "RxJava + Retrofit + OKHttp 訂閱成功");
}
@Override
public void onNext(JsonObject s) {
Log.d(TAG, "RxJava + Retrofit + OKHttp "+s.toString());
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "RxJava + Retrofit + OKHttp "+e.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, "RxJava + Retrofit + OKHttp onComplete");
}
});
複製代碼
輸出結果:
//請求地址
com.dn_alan.myapplication.MainActivity: https://wanandroid.com/wxarticle/chapters/json
//請求 Request 信息
com.dn_alan.myapplication.MainActivity: Request{method=GET, url=https://wanandroid.com/wxarticle/chapters/json, tags={class retrofit2.Invocation=com.dn_alan.myapplication.APIService.getWXarticles() []}};
//Rxjava 訂閱成功
com.dn_alan.myapplication.MainActivity: RxJava + Retrofit + OKHttp 訂閱成功
//RxJava + Retrofit + OKHttp 服務端返回的數據
D/com.dn_alan.myapplication.MainActivity: RxJava + Retrofit + OKHttp {"data":[{"children":[],"courseId":13,"id":408,"name":"鴻....}
//RxJava + Retrofit + OKHttp 網絡請求完成
D/com.dn_alan.myapplication.MainActivity: RxJava + Retrofit + OKHttp onComplete
//Retrofit + OKHttp 網絡請求完成
D/com.dn_alan.myapplication.MainActivity: Retrofit + OKHttp {"data":[{"children":.....}
複製代碼
經過打印咱們可以看出來 RxJava + Retrofit + OKHttp
, Retrofit + OKHttp
都請求成功了,經過請求地址 咱們發現最後 Retrofit 會拼接在一塊兒的。這樣使用是否是很是的爽。若是對 RxJava , OKHttp 源碼還不瞭解的建議看下我以前的文章先複習下,由於本章會涉及到它們源碼,這裏不會細講都是初略帶過,由於重點是 Retrofit
。
下面就是真正開始分析 Retrofit 怎麼配合 OKHttp 還有 RxJava 進行網絡訪問的。
package retrofit2;
...
public final class Retrofit {
....//省略代碼
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory; //配置的 OKhttp
this.baseUrl = baseUrl;//配置的 Http 地址
this.converterFactories = converterFactories; // 配置的轉換功能 好比 GSON,
this.callAdapterFactories = callAdapterFactories; // 配置的 RxJava
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
public <T> T create(final Class<T> service) {
....//動態代理主要代碼 後面講解
}
....//省略部分代碼
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;
Builder(Platform platform) {
this.platform = platform;
}
public Builder() {
this(Platform.get());
}
....//省略部分代碼
/** * * * 構建 OKHttpClient */
public Builder client(OkHttpClient client) {
return callFactory(checkNotNull(client, "client == null"));
}
/** * * 構建 OKHttpClient call */
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}
/** * Set the API base URL. * * @see #baseUrl(HttpUrl) 構建 URL */
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
return baseUrl(HttpUrl.get(baseUrl));
}
/** 構建 GSON */
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
/** * 構建 RXJava {@link Call}. */
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
public Retrofit build() {
// url
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//拿到 OKHttpClient
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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
//添加了一個默認的 DefaultCallAdapterFactory 用於進行協助 OKHttp 網絡請求
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// 初始化默認數據轉換器
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
//構建 Retrofit 對象
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
}
}
複製代碼
根據 Retrofit 內部代碼實現,咱們能夠知道主要作了 2 件事兒
下面分析 retrofit create 能夠說是核心方法了。
public <T> T create(final Class<T> service) {
//1. 檢查 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 @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
// 是不是 Object 類型
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {//通常不會執行這裏
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//2. 真正執行定義接口中的具體函數
//2.1 拿到 ServiceMethod 執行內部的 invoke 函數
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
複製代碼
對 JAVA 設計模式很熟的應該知道,這裏用到了動態代理模式,若是還有對動態代理或者其它設計模式不懂的能夠看我之前寫的設計模式系列文章 , 先看註釋 2 loadServiceMethod
函數
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
ServiceMethod<?> loadServiceMethod(Method method) {
//1. 拿到緩存中的 ServiceMethod
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;//1.1 若是存在就返回
//加了一個同步鎖
synchronized (serviceMethodCache) {
//在鎖裏面又獲取了一次
result = serviceMethodCache.get(method);
if (result == null) {//若是仍是爲空
result = ServiceMethod.parseAnnotations(this, method); //開始解析接口上的註解
//解析完成 存入緩存,避免下次再次解析相同的數據
serviceMethodCache.put(method, result);
}
}
return result;
}
複製代碼
經過上面代碼咱們知道就是從 Map 中拿到 ServiceMethod 對象,若是緩存中沒有就進行解析定義 Retrofit 網絡請求接口從而構建 ServiceMethod ,這裏若是有對 ConcurrentHashMap 不熟悉的推薦看下這篇文章ConcurrentHashMap 解析 。
下面咱們看下 ServiceMethod.parseAnnotations
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//1. 經過 retrofit 實例和 接口中的函數方法拿到一個 Retrofit 請求對象
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
//2. 拿到註解中的返回對象 :http://loveshisong.cn/%E7%BC%96%E7%A8%8B%E6%8A%80%E6%9C%AF/2016-02-16-Type%E8%AF%A6%E8%A7%A3.html
Type returnType = method.getGenericReturnType();
//內部判斷 type
if (Utils.hasUnresolvableType(returnType)) {
...//屬於拋一個異常
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
//3. 執行 HttpServiceMethod 解析
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
複製代碼
上面代碼咱們知道主要作了 3 件事兒
咱們來看下 RequestFactory.parseAnnotations(retrofit, method)
內部實現
//定義爲 final 不能爲繼承
final class RequestFactory {
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
static final class Builder {
....//省略部分代碼
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit; //拿到 retrofit 對象
this.method = method; //拿到調動的方法
this.methodAnnotations = method.getAnnotations();//獲取方法上面的全部註解
this.parameterTypes = method.getGenericParameterTypes();//獲取全部參數類型
this.parameterAnnotationsArray = method.getParameterAnnotations();//獲取參數中定義的註解
}
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
//1. 解析方法上的註解
parseMethodAnnotation(annotation);
}
...//省略屬性判斷
//拿到參數註解的數量,遍歷作一些處理
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], p == lastParameter);
}
...//省略屬性判斷
//2 . 實例化一個 RequestFactory 對象
return new RequestFactory(this);
}
}
複製代碼
咱們先來看下 parseMethodAnnotation
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
} else if (annotation instanceof HEAD) {
parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
} else if (annotation instanceof PATCH) {
parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
} else if (annotation instanceof POST) {
parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
} else if (annotation instanceof PUT) {
parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
} else if (annotation instanceof OPTIONS) {
parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
} else if (annotation instanceof HTTP) {
HTTP http = (HTTP) annotation;
parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
} else if (annotation instanceof retrofit2.http.Headers) {
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError(method, "@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
複製代碼
這裏不用註釋都知道幹嗎了吧,就是拿到當前函數上是否有請求的註解好比 GET,POST,....
,咱們看一下內部實現
private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
if (this.httpMethod != null) {
throw methodError(method, "Only one HTTP method is allowed. Found: %s and %s.",
this.httpMethod, httpMethod);
}
this.httpMethod = httpMethod;
this.hasBody = hasBody;
if (value.isEmpty()) {
return;
}
// Get the relative URL path and existing query string, if present.
int question = value.indexOf('?');
if (question != -1 && question < value.length() - 1) {
// Ensure the query string does not have any named parameters.
String queryParams = value.substring(question + 1);
Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
if (queryParamMatcher.find()) {
throw methodError(method, "URL query string \"%s\" must not have replace block. "
+ "For dynamic query parameters use @Query.", queryParams);
}
}
this.relativeUrl = value;
this.relativeUrlParamNames = parsePathParameters(value);
}
複製代碼
內部就是作一些請求連接的預處理,和最後一行代碼是對註解中的數據作一些處理返回一個 set 集合。
如今回到 ServiceMethod
類中 的 HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations( Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction; //是否支持 Kotlin
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;
//拿到當前網絡請求函數中的全部註解
Annotation[] annotations = method.getAnnotations();
Type adapterType;
if (isKotlinSuspendFunction) { //暫時沒有支持 全部先無論內部實現
...//
} else {
//返回接口中註解的返回類型
adapterType = method.getGenericReturnType();
}
//1. 建立 createCallAdapter 就是返回的是 RxJava 被觀察者對象或者是 OKHttp 的 默認 DefaultCallAdapterFactory 對象,根據註解返回值來判斷
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
if (responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
....//省略判斷
//2. 建立一個數據響應轉換 返回 GSON
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
//3. 拿到 OKHttp call Factory
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
//4. 建立一個 callAdapted
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}
複製代碼
上面仍是作一些對註解的預處理,處理完以後返回一個 ServiceMethod 對象。
從上面註釋 1 咱們能夠知道這裏根據註解解析返回的是一個 RxJava2CallAdapter
對象或者是 Retrofit 中 Builder 中默認的 DefaultCallAdapterFactory
當返回了 ServiceMethod
對象的時候又繼續執行了一個 invoke 函數,咱們直接看 HttpServiceMethod
的函數,由於它繼承於 ServiceMethod
@Override final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
複製代碼
上面拿到 OKHttpCall 而後執行一個 adapt 抽象函數,因爲直接解析註解咱們知道在其內部實例化的是 CallAdapter
對象,因此找它內部的 adapt 實現
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 的 adapt 函數
return callAdapter.adapt(call);
}
}
複製代碼
到了這裏咱們能夠知道 callAdapter.adapt 分別就目前知道實現了 2 個類,RxJava2CallAdapter
,和 DefaultCallAdapterFactory
,下面分別分析各自實現的 adapt(Call call) 函數
final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
@Override public Object adapt(Call<R> call) {
//這裏的 isAsync 就是配置 RxJava2CallAdapterFactory.createAsync() 內部有一個 布爾記錄
//1. 因爲咱們配置的是異步因此這裏返回 CallEnqueueObservable 被觀察者對象
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
Observable<?> observable;
//2. 只要請求接口中泛型參數不是 Result 通常狀況下執行 isBody 返回 BodyObservable 內部持有一個 CallEnqueueObservable 被觀察者對象
if (isResult) {//若是泛型參數是 Result
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
//這裏沒有指定因此爲空,也是在 RxJava2CallAdapterFactory 配置的時候指定
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
//定義的是不是 Flowable 被觀察者
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
//定義的是不是 Single 被觀察者
if (isSingle) {
return observable.singleOrError();
}
//定義的是不是 Maybe 被觀察者
if (isMaybe) {
return observable.singleElement();
}
//定義的是不是 Completable 被觀察者
if (isCompletable) {
return observable.ignoreElements();
}
//若是都不是的話 直接返回 BodyObservable
return RxJavaPlugins.onAssembly(observable);
}
}
複製代碼
到了這裏 api.getWXarticle();
若是定義的是被觀察者對象,那麼返回的就是 BodyObservable 內部持有一個 CallEnqueueObservable
的被觀察者對象。
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
private final @Nullable Executor callbackExecutor;
DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
...//省略部分代碼
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);
}
};
}
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) {
checkNotNull(callback, "callback == null");
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()) {
// 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(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
...//省略部分代碼
}
}
複製代碼
能夠看到若是咱們網絡請求接口函數返回值定義的是 Call 的話,那麼返回的就是實際返回的就是 ExecutorCallbackCall
對象
本章小結
能夠看到 create 函數主要經過動態代理來實現了調用接口中的函數,首先解析註解數據,而後解析函數返回值,最後根據函數返回值建立對應的實現類。
下一小節就實際介紹調用了
經過上一小節咱們知道 Call call = api.getWXarticles();
call 其實就是ExecutorCallbackCall
對象,那麼根據調用
Call<JsonObject> call = api.getWXarticles();
call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, retrofit2.Response<JsonObject> response) {
Log.d(TAG, "Retrofit + OKHttp " + response.body().toString());
}
@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.d(TAG, "Retrofit + OKHttp " + t.getMessage());
}
});
複製代碼
咱們直接看 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) {
//1. 檢查 callBack 是否爲空的狀態
checkNotNull(callback, "callback == null");
//2. 這裏的 delegate 其實就是 OKHttpClient 中的 Call
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()) {
// 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(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
....//省略部分代碼
}
複製代碼
根據上面註釋 2 咱們知道 delegate 就是 經過上層 HttpServiceMethod invoke 函數傳進來的
@Override final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
複製代碼
沒錯就是咱們熟悉的 OKHttpCall 對象,那麼咱們直接看 OkHttpCall.enqueue(new Callback()) 函數具體實現
//繼承自 OKHttp 中的 Call
final class OkHttpCall<T> implements Call<T> {
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
//拿到 OKHttp 中的 Call
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 {
//1. 建立一個 RealCall 對象
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
//2. 經過 RealCall 對象執行 enqueue 異步網絡請求
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) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
@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) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}
}
複製代碼
這裏主要作了 2 件事兒
咱們看一下注釋 1 由於 OKHttp 請求還須要 Request 對象,這裏咱們還沒看見因此,繼續在找
private okhttp3.Call createRawCall() throws IOException {
//1.
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
複製代碼
經過註釋 1 . 咱們知道 callFactory.newCall(requestFactory.create(args)) 返回的是 OKHTTP.call 對象,可是熟悉 OKHTTP 的知道 newCall 中須要傳入一個 Request 對象
//OKHttpClient.java
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
複製代碼
因此咱們直接看 requestFactory.create(args)
//1. 返回一個 Request 對象
okhttp3.Request create(Object[] args) throws IOException {
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
int argumentCount = args.length;
if (argumentCount != handlers.length) {
...//省略拋異常代碼
}
//構建一個 Retrofit Request 對象
RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl,
headers, contentType, hasBody, isFormEncoded, isMultipart);
if (isKotlinSuspendFunction) {
argumentCount--;
}
List<Object> argumentList = new ArrayList<>(argumentCount);
for (int p = 0; p < argumentCount; p++) {
argumentList.add(args[p]);
handlers[p].apply(requestBuilder, args[p]);
}
//2.
return requestBuilder.get()
.tag(Invocation.class, new Invocation(method, argumentList))
.build();
}
複製代碼
經過上面代碼咱們知道內部構建了一個 Retrofit 的 Request 對象,最後調用註釋 2 代碼,咱們繼續跟
// requestBuilder.get()
Request.Builder get() {
HttpUrl url;
HttpUrl.Builder urlBuilder = this.urlBuilder;
if (urlBuilder != null) { //若是 URL 爲空 從新構建一個
url = urlBuilder.build();
} else {
//這裏正在把 一個鏈接完整拼接在一塊兒 "https://wanandroid.com/wxarticle/chapters/json"
url = baseUrl.resolve(relativeUrl);
if (url == null) {
throw new IllegalArgumentException(
"Malformed URL. Base: " + baseUrl + ", Relative: " + relativeUrl);
}
}
//構建請求體
RequestBody body = this.body;
if (body == null) {
// Try to pull from one of the builders.
if (formBuilder != null) {
body = formBuilder.build();
} else if (multipartBuilder != null) {
body = multipartBuilder.build();
} else if (hasBody) {
// Body is absent, make an empty body.
body = RequestBody.create(null, new byte[0]);
}
}
//構建請求數據類型
MediaType contentType = this.contentType;
if (contentType != null) {
if (body != null) {
body = new ContentTypeOverridingRequestBody(body, contentType);
} else {
headersBuilder.add("Content-Type", contentType.toString());
}
}
//構建一個 Request 對象包含 url,headers,body
return requestBuilder
.url(url)
.headers(headersBuilder.build())
.method(method, body);
}
複製代碼
這裏 get 函數就是 Retrofit Request - > OKHttp Request 的一個過程。
如今 OKHttp Request ,RealCall 對象都有了 就能夠執行對應的異步函數,最後回調給調用層數據了。這裏若是對 OKHttp 運行機制不瞭解的能夠看根據 本文章前言 來進行閱讀。
經過 Retrofit create 小節講解,咱們知道 Observable<JsonObject> observable = api.getWXarticle();
Observable 其實就是 BodyObservable 它的上游是 CallEnqueueObservable 異步觀察者對象
對象,那麼根據調用
Observable<JsonObject> observable = api.getWXarticle();
//這裏的 observable 就是 BodyObservable 內部持有一個上游 CallEnqueueObservable 被觀察者
observable.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<JsonObject>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "RxJava + Retrofit + OKHttp 訂閱成功");
}
@Override
public void onNext(JsonObject s) {
Log.d(TAG, "RxJava + Retrofit + OKHttp " + s.toString());
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "RxJava + Retrofit + OKHttp " + e.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, "RxJava + Retrofit + OKHttp onComplete");
}
});
複製代碼
因爲這裏返回的是 BodyObservable
被觀察者,那麼根據執行流程在ObservableSubscribeOn.subscribeActual 的 s.onSubscribe(parent);
函數中訂閱成功。根據 RxJava 訂閱成功執行流程能夠知道下游會往上游走,最後會回調到 BodyObservable.subscribeActual
函數中,具體實現以下
@Override protected void subscribeActual(Observer<? super T> observer) {
upstream.subscribe(new BodyObserver<T>(observer));
}
複製代碼
根據 RxJava 源碼中的調用執行流程這裏的 upstream 就是上游 CallEnqueueObservable
異步被觀察者對象,也直接看它的 subscribeActual
函數具體實現
//CallEnqueueObservable.java
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
// 1.
Call<T> call = originalCall.clone();
//2.
CallCallback<T> callback = new CallCallback<>(call, observer);
//3.
observer.onSubscribe(callback);
if (!callback.isDisposed()) {
//4.
call.enqueue(callback);
}
}
複製代碼
總結下上面註解意思
咱們直接看 OKHttpCall enqueue 函數具體實現
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
...//省略部分代碼
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) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
@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) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}
複製代碼
這裏看到若是請求成功就直接回調到 OKhttp.callback.onResponse
中而後回調給 CallCallback 的 onResponse 函數,下面是具體實現
@Override public void onResponse(Call<T> call, Response<T> response) {
if (disposed) return;
try {
observer.onNext(response);
if (!disposed) {
terminated = true;
observer.onComplete();
}
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
if (terminated) {
RxJavaPlugins.onError(t);
} else if (!disposed) {
try {
observer.onError(t);
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
RxJavaPlugins.onError(new CompositeException(t, inner));
}
}
}
}
複製代碼
經過 observer.onNext(response);
一層傳一層最後傳遞到 ObservableSubscribeOn#SubscribeOnObserver.onNext()
函數中到這裏整個請求算是完成了。
到這裏 Retrofit 網絡請求的源碼已經分析完了 ,其中包括 Retrofit + OKHttp ,RxJava + Retrofit + OKHttp 相互之間怎麼配合網絡請求,也都進行講解了一遍。建議在學習 Retrofit 網絡請求以前,必定要知道 OKHttp 和 RxJava 的基本原理,否則 Retrofit 是看不下去的。