Retrofit源码分析小结
Retrofit源码分析&小结
简介
Retrofit是对Okhttp网络请求的二次封装,通过注解+动态代理的方式,简化了Okhttp的使用,使得通过简单的配置就可以像调用接口一样去请求网络接口;除此之外Retrofit还支持RxJava和kotlin的协程
基本使用
- 引入依赖库
//网络请求
implementation 'com.squareup.retrofit2:retrofit:2.9.0'//Retrofit基本库
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'//用于将结果转换成对象
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'//用于转换成RxJava支持的Observer对象
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'//RxJava对Android的支持
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'//Okhttp日志拦截器,用于打印接口请求相关log
//协程
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'//Retrofit对Kotlin协程的支持
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'//协程对Android的支持
implementation('androidx.lifecycle:lifecycle-runtime-ktx:2.6.0-alpha02')//协程对LifeCycle的支持
- 定义一个用于网络请求的服务接口
package com.example.myapplication.retrofit
import android.service.autofill.UserData
import io.reactivex.Observable
import retrofit2.Call
import retrofit2.http.*
interface IUserServer {
/**
* 以GET方式请求
*/
@GET("getUserInfo/")
fun getUserInfo(@Query("userId") userId: String): Call<UserData>
/**
* 以POST方式请求,并结合RxJava
*/
@POST("getUserInfo/")
@FormUrlEncoded
fun getUserInfoByRxJava(@Field("userId") userId: String): Observable<UserData>
/**
* 结合kotlin协程完成线程切换
*/
@GET("banner/json")
suspend fun getUserInfoBySuspend2(@Query("userId") userId: String): UserData
}
- 创建Retrofit对象和自定义接口代理实现对象
val retrofit = Retrofit.Builder()
.baseUrl("http://www.xxx.com/")
.addConverterFactory(GsonConverterFactory.create())//支持Gson
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//支持Rxjava
.build()
val server = retrofit.create(IUserServer::class.java)
- 普通发起网络请求
val userInfo = server.getUserInfo("1").execute()//同步执行
server.getUserInfo("1").enqueue(object : Callback<UserData> {//异步执行
override fun onResponse(call: Call<UserData>, response: Response<UserData>) {
//网络请求返回结果
}
override fun onFailure(call: Call<UserData>, t: Throwable) {
//网络请求错误
}
})
- 结合RxJava
server.getUserInfoByRxJava("1").subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<UserData> {
override fun onSubscribe(d: Disposable?) {
//网络请求前
}
override fun onNext(value: UserData?) {
//网络请求返回结果
}
override fun onError(e: Throwable?) {
//网络请求错误
}
override fun onComplete() {
//网络请求结束
}
})
- 结合Kotlin协程
lifecycleScope.launch {
val userInfo = withContext(Dispatchers.IO) {
val userInfo = server.getUserInfoBySuspend2("1")//子线程中请求网络
}
//回到主线程
Log.i("testRetrofit", "userInfo:$userInfo")
}
核心源码分析
1. Retrofit.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 the method is a method from Object then defer to normal invocation.
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);//开始解析该方法并返回接口请求对象,比如Call、Observable(需结合Rxjava)
}
});
}
```
-
在validateServiceInterface方法中,如果配置了Retrofit.Builder().validateEagerly(true),会立刻根据注解解析接口中定义的所有方法,如果是false,则会等待方法调用时才会解析接口中的方法;
设置为true的好处是在创建接口代理时就能检查出各个方法配置的注解、返回值等是否正确,如果为默认的false,则只有在方法调用时才能发现问题;
所以建议在debug阶段设置为true便于及早发现问题,release阶段设置false以提高性能
private void validateServiceInterface(Class<?> service) { ... ... if (validateEagerly) { Platform platform = Platform.get(); for (Method method : service.getDeclaredMethods()) {//遍历所有方法,根据注解进行解析 if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) { loadServiceMethod(method); } } } }
-
默认实现中接口返回的Call实际上是一个Retrofit中定义的一个接口,定义了同步请求和异步请求的方法;
public interface Call<T> extends Cloneable { ... ... /** * Synchronously send the request and return its response. * * @throws IOException if a problem occurred talking to the server. * @throws RuntimeException (and subclasses) if an unexpected error occurs creating the request or * decoding the response. */ Response<T> execute() throws IOException; /** * Asynchronously send the request and notify {@code callback} of its response or if an error * occurred talking to the server, creating the request, or processing the response. */ void enqueue(Callback<T> callback); ... ... }
-
Call的实现类根据是否有注解@SkipCallbackExecutor来决定,当有该注解时,Call的实现类是OkHttpCall.java,里面封装了OkHttp的网络请求,如果没有该注解,则Call实现类是DefaultCallAdapterFactory.ExecutorCallbackCall;这个类仅仅是个代理类,真正实现网络请求的还是OkHttpCall;
代理类存在的意义是Okhttp进行异步请求返回结果后,会先通过Handler将线程切换到主线程再返回结果final class OkHttpCall<T> implements Call<T> { @Override 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) { } @Override public void onFailure(okhttp3.Call call, IOException e) { callFailure(e); } } ... } @Override public Response<T> execute() throws IOException { okhttp3.Call call; ... return parseResponse(call.execute()); } }
static final class ExecutorCallbackCall<T> implements Call<T> { final Executor callbackExecutor;//在主线程执行,实现类是Platform.Android.MainThreadExecutor final Call<T> delegate;//这个实现类是OkHttpCall @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(() -> { //切换到主线程执行 callback.onResponse(ExecutorCallbackCall.this, response); } }); } @Override public void onFailure(Call<T> call, final Throwable t) { //切换到主线程执行 callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t)); } }); } @Override public Response<T> execute() throws IOException { return delegate.execute();//在当前所在线程执行 } }
2. 注解的解析过程和使用
-
在Retrofit.create方法中,loadServiceMethod方法中会先从缓存中查找ServiceMethod对象,如果之前有解析过则直接返回,如果没有则调用ServiceMethod.parseAnnotations方法返回一个ServiceMethod对象
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; }
-
接着会调用RequestFactory.parseAnnotations方法真正进行注解的解析,并构建一个HttpServiceMethod对象返回
abstract class ServiceMethod<T> { static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) { //真正解析方法上的注解入口 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."); } return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); }
-
RequestFactory.Builder中解析方法中的注解,可以理解为RequestFactory对象保存着所有请求的数据
final class RequestFactory { static RequestFactory parseAnnotations(Retrofit retrofit, Method method) { return new Builder(retrofit, method).build(); } static final class Builder { final Annotation[] methodAnnotations;//方法上的注解 final Annotation[][] parameterAnnotationsArray;//方法参数上的注解 final Type[] parameterTypes;//参数类型 @Nullable String httpMethod;//请求的方式get、post等 @Nullable String relativeUrl;//解析处理后的请求接口 @Nullable Headers headers;//封装的请求头信息 boolean isKotlinSuspendFunction; //用于标记是否kotlin协程中suspend方法 ... private Headers parseHeaders(String[] headers) {}//解析请求头信息 private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) //解析请求方式和接口路径 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); } ... } private ParameterHandler<?> parseParameterAnnotation(){//解析参数上注解 if (annotation instanceof Path) { } else if (annotation instanceof Query) { } else if (annotation instanceof QueryName) { } else if (annotation instanceof QueryMap) { } else if (annotation instanceof Header) { } else if (annotation instanceof HeaderMap) { } else if (annotation instanceof Field) { } else if (annotation instanceof FieldMap) { } else if (annotation instanceof Body) { } ... } } }
-
请求参数的使用,是在真正发起网络请求OkhttpCall.createRawCall()方法中创建Okhttp Call对象的时候,通过RequestFactory.create方法将所有请求参数封装成OkHttp的Request对象
class OkHttpCall{
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
return call;
}
}
class RequestFactory{
okhttp3.Request create(Object[] args) throws IOException {
RequestBuilder requestBuilder =
new RequestBuilder(
httpMethod,
baseUrl,
relativeUrl,
headers,
contentType,
hasBody,
isFormEncoded,
isMultipart);
if (isKotlinSuspendFunction) {//协程suspen方法会自动在最后面加一个Continuation对象类型参数,所以实际请求时要去掉
// The Continuation is the last parameter and the handlers array contains null at that index.
argumentCount--;
}
List<Object> argumentList = new ArrayList<>(argumentCount);
for (int p = 0; p < argumentCount; p++) {
argumentList.add(args[p]);
handlers[p].apply(requestBuilder, args[p]);
}
//构建okhttp3.Request对象
return requestBuilder.get().tag(Invocation.class, new Invocation(method, argumentList)).build();
}
}
3. RxJava2CallAdapterFactory:对Rxjava的支持,将默认返回的的Call对象转换成Observer对象
- 当调用接口方法的时候,通过动态代理默认会调用HttpServiceMethod.CallAdapted的invoke方法,而CallAdapted继承自HttpServiceMethod,并重写了adapt方法;
adapt方法用于封装Call对象并将结果转化成我们定义的接口方法所声明的返回对象
class HttpServiceMethod{
@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);
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;//默认的适配器是通过DefaultCallAdapterFactory动态生成的CallAdapter实现类
CallAdapted(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;//通过RxJava2CallAdapterFactory生成的Rxjava2适配器RxJava2CallAdapter
}
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);//调用适配器,将返回结果转换成我们定义的返回类型,比如默认是返回Call,Rxjava返回的是Observer对象
}
}
}
- RxJava2CallAdapterFactory在创建时,可以选择调用create、createAsync、createWithScheduler(Scheduler)方法进行创建,他们的主要区别是create是调用Call.execute方法请求网络,也就是在当前线程执行;
而createAsync则是调用Call.enqueue方法请求网络,也就是异步请求;createWithScheduler可以传入一个Scheduler,指定网络请求在哪个线程上执行,通过observable.subscribeOn(scheduler)实现
public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
/**
* Returns an instance which creates synchronous observables that do not operate on any scheduler
* by default.
*/
public static RxJava2CallAdapterFactory create() {
return new RxJava2CallAdapterFactory(null, false);
}
/**
* Returns an instance which creates asynchronous observables. Applying
* {@link Observable#subscribeOn} has no effect on stream types created by this factory.
*/
public static RxJava2CallAdapterFactory createAsync() {
return new RxJava2CallAdapterFactory(null, true);
}
public static RxJava2CallAdapterFactory createWithScheduler(Scheduler scheduler) {
if (scheduler == null) throw new NullPointerException("scheduler == null");
return new RxJava2CallAdapterFactory(scheduler, false);
}
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
...
return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
isSingle, isMaybe, false);
}
}
- 调用RxJava2CallAdapter.adapt方法,将Call传入并返回Observer
final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
@Override public Object adapt(Call<R> call) {
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);//真正网络请求包装在在这里面
...
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
...
return observable;
}
}
- 当外部调用Observer的subscribe方法时,后就会立刻执行CallExecuteObservable/CallExecuteObservable里的subscribeActual方法,从而调用Call的execute或者enqueue方法实现网络请求
class Observable{
public final void subscribe(Observer<? super T> observer) {
subscribeActual(observer);
}
}
final class CallExecuteObservable<T> extends Observable<Response<T>> {
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
Call<T> call = originalCall.clone();
Response<T> response = call.execute();//发起网络请求并返回结果
if (!call.isCanceled()) {//传递给onNext方法
observer.onNext(response);
}
if (!call.isCanceled()) {
terminated = true;
observer.onComplete();
}
}
}
4. GsonConverterFactory:网络请求返回结果的处理
- 在OkHttpCall发起网络请求后,会调用parseResponse方法解析返回结果,然后通过结果转换器进行转换,默认转换器是BuiltInConverters,如果配置了GsonConverterFactory,则支持转换成我们自定义对象,实现类是GsonResponseBodyConverter
class OkHttpCall{
@Override
public Response<T> execute() throws IOException {
okhttp3.Call call;
call = getRawCall();
...
return parseResponse(call.execute());
}
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
...
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
//调用结果转换器进行转换,这里会根据声明方法返回值类型选择不同转换器,比如返回默认的ResponseBody,则使用自带的BuiltInConverters转换,返回自定义对象则会使用GsonResponseBodyConverter进行转换
T body = responseConverter.convert(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;
}
}
}
- Retrofit自带的默认转换器BuiltInConverters,支持处理返回类型是ResponseBody/Void 或者kotlin的Unit
final class BuiltInConverters extends Converter.Factory {
/** Not volatile because we don't mind multiple threads discovering this. */
private boolean checkForKotlinUnit = true;
@Override
public @Nullable 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;
}
if (checkForKotlinUnit) {
try {
if (type == Unit.class) {
return UnitResponseBodyConverter.INSTANCE;
}
} catch (NoClassDefFoundError ignored) {
checkForKotlinUnit = false;
}
}
return null;
}
}
- Gson转换器GsonResponseBodyConverter,支持自定义对象类型的转换
final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter<T> adapter;
GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
return adapter.read(jsonReader);
} finally {
value.close();
}
}
}
5. 对kotlin协程的支持
- 判断是否kotlin suspend方法,在kotlin中suspend修饰的方法在编译成字节码并反编译成java代码后会发现方法参数里最后会多一个Continuation类型的参数,用于对协程的支持
kotlin字节码反编译后的java代码
public interface IUserServer {
... ...
@GET("banner/json")
@Nullable
Object getUserInfoBySuspend2(@Query("userId") @NotNull String var1, @NotNull Continuation var2);
}
- Retrofit在RequestFactory解析方法参数时做判断
class RequestFactory{
class Builder{
boolean isKotlinSuspendFunction;
private @Nullable ParameterHandler<?> parseParameter(
int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
try {
if (Utils.getRawType(parameterType) == Continuation.class) {//判断是否suspend协程方法
isKotlinSuspendFunction = true;
return null;
}
} catch (NoClassDefFoundError ignored) {
}
}
}
}
- 根据方法返回类型,返回不同的HttpServiceMethod,当suspend方法直接返回自定义数据类型时(比如 UserData),返回的是SuspendForBody对象; 如果方法返回的是Response,则返回SuspendForResponse对象,这两个返回对象其实差不多,只是返回类型不一样
class HttpServiceMethod{
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response<T>.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
}
if (continuationWantsResponse) {
//返回Response<UserData>类型结果
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForResponse<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
//返回UserData类型结果
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForBody<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}
}
- 继续以SuspendForBody分析,在adapt方法被调用时,Retrofit会调用kotlin的扩展方法await/awaitNullable
static final class SuspendForBody<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;
private final boolean isNullable;
@Override
protected Object adapt(Call<ResponseT> call, Object[] args) {
call = callAdapter.adapt(call);//这里是默认的DefaultCallAdapterFactorys产生的Adapter
//获取suspend最后一个参数用于协程
Continuation<ResponseT> continuation = (Continuation<ResponseT>) args[args.length - 1];
try {//调用Retrofit使用kotlin对Call类的扩展方法
return isNullable //返回的对象是否可为空
? KotlinExtensions.awaitNullable(call, continuation)
: KotlinExtensions.await(call, continuation);
} catch (Exception e) {
return KotlinExtensions.suspendAndThrow(e, continuation);
}
}
}
- kotlin对Call方法扩展解析,协程方法中会异步发起网络请求并返回结果,当结束后会恢复到父协程地方继续执行
//这里是suspend方法,执行时协程会挂起
suspend fun <T : Any> Call<T>.await(): T {
return suspendCancellableCoroutine { continuation ->
continuation.invokeOnCancellation {
cancel()//设置协程取消时的回调,调用Call的cancel方法
}
enqueue(object : Callback<T> {//调用Call方法异步请求网络
override fun onResponse(call: Call<T>, response: Response<T>) {
if (response.isSuccessful) {
val body = response.body()
if (body == null) {
val invocation = call.request().tag(Invocation::class.java)!!
val method = invocation.method()
val e = KotlinNullPointerException("Response from " +
method.declaringClass.name +
'.' +
method.name +
" was null but response body type was declared as non-null")
continuation.resumeWithException(e)//恢复协程并抛出异常
} else {
continuation.resume(body)//恢复协程并返回结果
}
} else {//恢复协程并抛出异常
continuation.resumeWithException(HttpException(response))
}
}
override fun onFailure(call: Call<T>, t: Throwable) {
continuation.resumeWithException(t)//恢复协程并抛出异常
}
})
}
}
小结
-
Retrofit实现原理:
答:Retrofit通过Create方法创建我们自定义接口实例时,会为我们接口创建一个动态代理;当调用接口方法的时候,会先根据配置的注解解析这个方法的信息,包括请求路径、请求参数、返回值等等,并把解析后的信息封装成对象并缓存起来;
然后根据方法的信息封装成一个Call对象,这个Call对象的默认实现类是OkHttpCall,内部是通过Okhttp发起同步或者异步网络请求;
然后调用Call的execute同步或者enqueue异步方法进行网络请求,返回结果后,会调用转换器对结果进行转换,默认是返回ResponseBody,也可以通过配置Gson转换器转成我们自定义类型;
如果需要对RxJava支持,返回Observer对象,则是需要配置一个Rxjava的CallAdapter,在适配器中将Call对象封装到Observer对象中并返回,当Observer的subscribe方法调用时会触发Call的网络请求操作,最后通过RxJava对结果分发;
如果需要对kotlin协程支持,Retrofit在对方法解析时会判断是否suspend方法,如果是的话,会执行Call的kotlin扩展方法,扩展方法也是suspend类型,在扩展方法中会挂起协程,通过Call对象执行网络请求操作,最后通过Continuation.resume方法恢复协程到父协程调用的地方 -
静态代理和动态代理的区别?
答:静态代理是指在代码编写的时候,代理类和被代理类的关系就确定了,编译后也会生成代理类字节码文件;而动态代理是指在运行时期,动态的通过反射方式为被代理的接口生成一个代理类,当调用这个接口的方法时,都会进入InvokeHandler的invoke方法中,从而实现对这个被代理接口的统一处理;
静态代理适合被代理的类比较少的情况,如果代理的类比较多,而且不需要做统一处理,则动态代理方便很多 -
Retrofit返回结果是如何切换到主线程的?
答:Retrofit会通过系统属性来判断是否Android平台,如果是Android平台,则会创建一个执行器,内部会创建一个主线程Looper的Handler,当网络请求结束返回结果时,会封装一个Runnable通过这个主线程Handler去执行,从而切换到主线程;
或者通过RxJava或者协程进行线程切换 -
对Kotlin协程(suspend方法)的支持
- 判断协程方法条件:判断方法最后一个参数是否是Continuation.class类型
- Retrofit使用kotlin对Call类扩展了suspend方法,在suspend方法中执行Call的网络请求,然后通过Continuation的resume方法恢复协程挂起并返回结果
- 什么时候切回主线程的?在协程中调用continuation.resume方法后会自动回到它父协程所在线程,也就是主线程继续执行