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
}
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) {
//网络请求错误
}
})
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() {
//网络请求结束
}
})
lifecycleScope.launch {
val userInfo = withContext(Dispatchers.IO) {
val userInfo = server.getUserInfoBySuspend2("1")//子线程中请求网络
}
//回到主线程
Log.i("testRetrofit", "userInfo:$userInfo")
}
```
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();//在当前所在线程执行
}
}
在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
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对象
}
}
}
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);
}
}
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;
}
}
class Observable{
public final void subscribe(Observer super T> observer) {
subscribeActual(observer);
}
}
final class CallExecuteObservable extends Observable> {
@Override protected void subscribeActual(Observer super Response> observer) {
Call call = originalCall.clone();
Response response = call.execute();//发起网络请求并返回结果
if (!call.isCanceled()) {//传递给onNext方法
observer.onNext(response);
}
if (!call.isCanceled()) {
terminated = true;
observer.onComplete();
}
}
}
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;
}
}
}
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;
}
}
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();
}
}
}
kotlin字节码反编译后的java代码
public interface IUserServer {
... ...
@GET("banner/json")
@Nullable
Object getUserInfoBySuspend2(@Query("userId") @NotNull String var1, @NotNull Continuation var2);
}
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) {
}
}
}
}
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);
}
}
}
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);
}
}
}
//这里是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方法)的支持