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

/**

* 以POST方式请求,并结合RxJava

*/

@POST("getUserInfo/")

@FormUrlEncoded

fun getUserInfoByRxJava(@Field("userId") userId: String): Observable

/**

* 结合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 {//异步执行

override fun onResponse(call: Call, response: Response) {

//网络请求返回结果

}

override fun onFailure(call: Call, t: Throwable) {

//网络请求错误

}

})

结合RxJava

server.getUserInfoByRxJava("1").subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(object : Observer {

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 create(final Class 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 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 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 callback);

... ...

}

Call的实现类根据是否有注解@SkipCallbackExecutor来决定,当有该注解时,Call的实现类是OkHttpCall.java,里面封装了OkHttp的网络请求,如果没有该注解,则Call实现类是DefaultCallAdapterFactory.ExecutorCallbackCall;这个类仅仅是个代理类,真正实现网络请求的还是OkHttpCall; 代理类存在的意义是Okhttp进行异步请求返回结果后,会先通过Handler将线程切换到主线程再返回结果 final class OkHttpCall implements Call {

@Override

public void enqueue(final Callback 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 execute() throws IOException {

okhttp3.Call call;

...

return parseResponse(call.execute());

}

}

static final class ExecutorCallbackCall implements Call {

final Executor callbackExecutor;//在主线程执行,实现类是Platform.Android.MainThreadExecutor

final Call delegate;//这个实现类是OkHttpCall

@Override

public void enqueue(final Callback callback) {

delegate.enqueue(

new Callback() {

@Override

public void onResponse(Call call, final Response response) {

callbackExecutor.execute(() -> {

//切换到主线程执行

callback.onResponse(ExecutorCallbackCall.this, response);

}

});

}

@Override

public void onFailure(Call call, final Throwable t) {

//切换到主线程执行

callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));

}

});

}

@Override

public Response 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 {

static ServiceMethod 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 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 call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);

return adapt(call, args);

}

protected abstract @Nullable ReturnT adapt(Call call, Object[] args);

static final class CallAdapted extends HttpServiceMethod {

private final CallAdapter callAdapter;//默认的适配器是通过DefaultCallAdapterFactory动态生成的CallAdapter实现类

CallAdapted(

RequestFactory requestFactory,

okhttp3.Call.Factory callFactory,

Converter responseConverter,

CallAdapter callAdapter) {

super(requestFactory, callFactory, responseConverter);

this.callAdapter = callAdapter;//通过RxJava2CallAdapterFactory生成的Rxjava2适配器RxJava2CallAdapter

}

@Override

protected ReturnT adapt(Call 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 implements CallAdapter {

@Override public Object adapt(Call call) {

Observable> 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 observer) {

subscribeActual(observer);

}

}

final class CallExecuteObservable extends Observable> {

@Override protected void subscribeActual(Observer> observer) {

Call call = originalCall.clone();

Response 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 execute() throws IOException {

okhttp3.Call call;

call = getRawCall();

...

return parseResponse(call.execute());

}

Response 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 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 implements Converter {

private final Gson gson;

private final TypeAdapter adapter;

GsonResponseBodyConverter(Gson gson, TypeAdapter 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 HttpServiceMethod 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.

responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);

continuationWantsResponse = true;

}

if (continuationWantsResponse) {

//返回Response类型结果

return (HttpServiceMethod)

new SuspendForResponse<>(

requestFactory,

callFactory,

responseConverter,

(CallAdapter>) callAdapter);

} else {

//返回UserData类型结果

return (HttpServiceMethod)

new SuspendForBody<>(

requestFactory,

callFactory,

responseConverter,

(CallAdapter>) callAdapter,

continuationBodyNullable);

}

}

}

继续以SuspendForBody分析,在adapt方法被调用时,Retrofit会调用kotlin的扩展方法await/awaitNullable

static final class SuspendForBody extends HttpServiceMethod {

private final CallAdapter> callAdapter;

private final boolean isNullable;

@Override

protected Object adapt(Call call, Object[] args) {

call = callAdapter.adapt(call);//这里是默认的DefaultCallAdapterFactorys产生的Adapter

//获取suspend最后一个参数用于协程

Continuation continuation = (Continuation) 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 Call.await(): T {

return suspendCancellableCoroutine { continuation ->

continuation.invokeOnCancellation {

cancel()//设置协程取消时的回调,调用Call的cancel方法

}

enqueue(object : Callback {//调用Call方法异步请求网络

override fun onResponse(call: Call, response: Response) {

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: 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方法后会自动回到它父协程所在线程,也就是主线程继续执行

参考阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: 

发表评论

返回顶部暗黑模式