在說Retrofit之前 必須有了解動態(tài)代理,因為Retrofit的核心就是動態(tài)代理。
動態(tài)代理
- 動態(tài)代理就是在運行時動態(tài)創(chuàng)建某個interface的實例,通過Proxy.newProxyInstance產(chǎn)生代理類,調(diào)用接口的任何方法的時候,都會被InvocationHandler的invoke方法攔截,拿到傳輸?shù)膮?shù)信息,可以做一些相應(yīng)的處理。
Retrofit的Calladapter和Converter兩個重要的對象
- calladapter 是適配器,幫助我們返回是適配返回的類型,
- Converter 數(shù)據(jù)組裝器,負責(zé)把服務(wù)器返回的數(shù)據(jù)ResponseBody轉(zhuǎn)換成T對象。
- 先看一下創(chuàng)建過程 也就是create
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
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
retrofit 的creat 主要是動態(tài)代理模式,invoke方法。然后就是核心:loadServiceMethod(method)和 invoke(args)
- loadServiceMethod
這個方法主要將網(wǎng)絡(luò)請求中的信息初步做處理,在api service中注解(@POST @GET)還有參數(shù),進行解析,解析后有生成了一個RequestFactory的工廠對象,并利用這個對象創(chuàng)建了CallAdapter。 - invoke(args)
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
主要是根絕loadserviceMethod 創(chuàng)建的RequestFactory 以及轉(zhuǎn)換的參數(shù) 生產(chǎn)一個OkhttpCall對象。其實這個OkhttpCall對象就是對OKhttp RealCall的一個包裝。
看一下OkhttpCall的網(wǎng)絡(luò)請求:
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
okhttp3.Call call;
synchronized (this) {
...
if (call == null && failure == null) {
try {
call = rawCall = createRawCall();
}
}
...
call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
//解析請求返回值
response = parseResponse(rawResponse);
}
...
try {
callback.onResponse(OkHttpCall.this, response);
}
@Override
public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
}
}
});
}
- 調(diào)用了一個createRawCall()方法,創(chuàng)建rawCall,這個rawCall其實指代的就是Okhttp3的call,也就是OkHttp進行網(wǎng)絡(luò)請求調(diào)用的一個調(diào)度器.
- 創(chuàng)建好OkHttp的call后,就開始調(diào)用enqueue進行異步請求.
3.okhttp3.Response這個響應(yīng),retrofit在收到結(jié)果后,進行新一輪的解析 response = parseResponse(rawResponse),以Response對象的形式返回給開發(fā)者。
CallAdapted
loadserviceMethod 返回的是CallAdapted對象。
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
Type adapterType;
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType =
Utils.getParameterLowerBound(
0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response<T>.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
}
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
adapterType = method.getGenericReturnType();
}
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
...
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
public CallAdapter<?, ?> nextCallAdapter(
@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
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;
}
}
CallAdapter根據(jù)returnType和annotation的類型,從calladapterfactories中進行查找,返回所對應(yīng)的網(wǎng)絡(luò)請求適配器。
總結(jié)一下:
- 開始動態(tài)代理調(diào)用loadServiceMethod方法,解析接口中的注解參數(shù)和頭部信息。
- 根絕接口返回類型,從適配工廠集合中查詢,生產(chǎn)相應(yīng)的適配器CallAdapter,相同的形式取出數(shù)據(jù)轉(zhuǎn)換器Converter。
- 用生產(chǎn)的CallAdapter 調(diào)用invoke方法,創(chuàng)建okhttpCall對象,然后進行網(wǎng)絡(luò)請求,響應(yīng)結(jié)果進行實體類轉(zhuǎn)換,
- 創(chuàng)建好okhttpcall以后 調(diào)用CallAdapter的adapter,返回Rxjava的Observable.single或者call對象。
Retrofit結(jié)合動態(tài)代理,不用關(guān)心真正的接口方法,對符合規(guī)范的接口進行統(tǒng)一管理,以統(tǒng)一注解的方式和參數(shù),拼接成request的請求。
retrofit是怎么將子線程切換到主線程
- 添加默認適配的時候 將callbackExecutor作為一個參數(shù)傳進去了。
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
...
@Override
public void enqueue(final Callback<T> callback) {
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));
}
});
}
callbackExecutor 是一個線程調(diào)度器。在這里執(zhí)行了一個異步操作delegate.enqueue.,在默認初始化中callbackExecutor = platform.defaultCallbackexcetuor().他其實內(nèi)部調(diào)用的就是一個 new MainThreadExecutor(). handler.post(s) 內(nèi)部使用使用Handler將響應(yīng)拋到了主線程中去。這就是子線程切換到主線程的核心方法。