Retrofit源码分析(2.9.0最新版)

Retrofit源码分析

前言

本文基于retrofit 2.9.0,在2.6.0版本之后,retrofit对kotlin协程进行了支持,主要是加入了一些kotlin的扩展函数。
如有谬误,还请各位大佬指正。

概述

Retrofit并不是一个网络请求库,它的作用主要是为了简化网络请求的构建和对返回数据的处理。它的网络请求是通过square自家的OkHttp实现的。

主要优点

  • 可以在构建retrofit时添加多种类型的转换器,让我们不用再手动解析返回的数据了
  • 将接口的定义与使用分离开来,实现解耦
  • 可以和kotlin协程、RxJava等配合使用简化回调,优雅地实现网络请求
  • 请求速度快,使用OkHttp实现进行请求

简单使用

1.首先创建一个请求接口:

interface PlaceService {
    @GET("v2/place?lang=zh_CN")
    fun searchPlaces(@Query("query") query: String): Call<PlaceModel>
}

2.再通过如下代码通过OkHttp发起网络请求

//构建Retrofit对象
val retrofit = Retrofit.Builder()
	.baseUrl(url)
    .addConverterFactory(GsonConverterFactory.create())
    .build()
//创建接口实例
val placeService = retrofit.create(PlaceService::class.java)
//通过接口实例调用请求方法获取Call对象
val call = placeService.searchPlaces("xxx")
//通过Call的enqueue或execute方法进行异步或同步请求
call.enqueue(object : Callback<PlaceModel> {
    override fun onFailure(call: Call<PlaceModel>, t: Throwable) {
        ...
    }

    override fun onResponse(call: Call<PlaceModel>, response: Response<PlaceModel>) {
        ...
    }
})

需要注意的是:retrofit的请求URL是由构建retrofit对象时baseUrl中的参数和@GET注解中的Url拼接而来的。

更多Retrofit的使用在我另一篇博客:Retrofit的简单使用

源码分析

1.Retrofit的创建

Retrofit.Builder()

public Builder() {
    this(Platform.get());
}

Platform.get()

这个方法根据不同的平台返回不同的线程池,在Android平台会创建MainThreadExecutor,它会通过handler将Runnable回调到主线程执行:

class Platform {
    private static final Platform PLATFORM = findPlatform();

    static Platform get() {
        return PLATFORM;
    }

    private static Platform findPlatform() {
        return "Dalvik".equals(System.getProperty("java.vm.name"))
            ? new Android() //
            : new Platform(true);
    }

    static final class Android extends Platform {
        Android() {
            super(Build.VERSION.SDK_INT >= 24);
        }

        @Override
        public Executor defaultCallbackExecutor() {	//默认回调线程池为MainThreadExecutor
            return new MainThreadExecutor();
        }

        @Nullable
        @Override
        Object invokeDefaultMethod(
            Method method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
            if (Build.VERSION.SDK_INT < 26) {
                throw new UnsupportedOperationException(
                    "Calling default methods on API 24 and 25 is not supported");
            }
            return super.invokeDefaultMethod(method, declaringClass, object, args);
        }

        static final class MainThreadExecutor implements Executor {
            private final Handler handler = new Handler(Looper.getMainLooper());	//创建主线程的handler

            @Override
            public void execute(Runnable r) {
                handler.post(r);	//通过handler将Runnable发送至主线程
            }
        }
    }
}

Retrofit.Builder.build()

这个Builder是Retrofit的内部类,主要用于构建Retrofit对象。它的这个build方法就是用于创建Retrofit实例。

public Retrofit build() {
    if (baseUrl == null) {	//baseUrl为null,直接抛出异常
        throw new IllegalStateException("Base URL required.");
    }

    //callFactory由Builder的callFactory方法设置,如果需要对OkHttpClient进行配置,
    //就可以构建OkHttpClient对象,设置给callFactory并通过callFactory方法传入即可
    okhttp3.Call.Factory callFactory = this.callFactory;
    //否则直接创建OkHttpClient对象
    if (callFactory == null) {
        callFactory = new OkHttpClient();
    }

    Executor callbackExecutor = this.callbackExecutor;
    if (callbackExecutor == null) {
        //获取对应平台的defaultCallbackExecutor,安卓平台会直接创建MainThreadExecutor,上面代码提到过
        callbackExecutor = platform.defaultCallbackExecutor();
    }

    //主要用于存储对Call进行转化的对象
    List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
    callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

    //转换器列表,构建Retrofit对象时通过addConvertFactory可以添加转换器
    List<Converter.Factory> converterFactories =
        new ArrayList<>(
        1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

    // Add the built-in converter factory first. This prevents overriding its behavior but also
    // ensures correct behavior when using converters that consume all types.
    //先添加内置转换器,保证转换时正确的行为
    converterFactories.add(new BuiltInConverters());
    converterFactories.addAll(this.converterFactories);
    converterFactories.addAll(platform.defaultConverterFactories());

    //将上面的属性传入,创建Retrofit对象
    return new Retrofit(
        callFactory,
        baseUrl,
        unmodifiableList(converterFactories),
        unmodifiableList(callAdapterFactories),
        callbackExecutor,
        validateEagerly);
}

2.Call对象的创建

上面简单使用中通过retrofit的create方法来创建了接口的动态代理对象

val placeService = retrofit.create(PlaceService::class.java)

再通过这个动态代理对象调用接口中的方法就创建了Call对象。

val call = placeService.searchPlaces("xxx")

Retrofit.create(final Class service)

public <T> T create(final Class<T> service) {
    validateServiceInterface(service);
    //下面直接返回了一个动态代理对象
    return (T)
        Proxy.newProxyInstance(
        service.getClassLoader(),
        new Class<?>[] {service},
        //当我们通过动态代理对象调用接口中的方法时,最终会调用下面接口中的invoke方法
        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的方法,如toString等,就进行正常调用
                if (method.getDeclaringClass() == Object.class) {
                    return method.invoke(this, args);
                }
                args = args != null ? args : emptyArgs;
                //default method指的就是接口中定义的非抽象非静态有方法体的方法
                //我们一般不会中接口中这样声明方法,因此默认调用下面的loadServiceMethod(method).invoke(args)
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);
            }
        });
}

Retrofit.loadServiceMethod(Method method)

ServiceMethod<?> loadServiceMethod(Method method) {
    //先从缓存中获取
    ServiceMethod<?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    //没有缓存就通过ServiceMethod.parseAnnotations(this, method)创建,并将其加入缓存
    synchronized (serviceMethodCache) {
        result = serviceMethodCache.get(method);
        if (result == null) {
            result = ServiceMethod.parseAnnotations(this, method);
            serviceMethodCache.put(method, result);
        }
    }
    return result;
}


//ServiceMethod.java
abstract class ServiceMethod<T> {
    static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
        //创建RequestFactory对象
        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.");
        }
		
        //通过接口中的注解来构建一个可以重用的ServiceMethod对象
        return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
    }

    abstract @Nullable T invoke(Object[] args);
}

上面通过RequestFactory.parseAnnotations(retrofit, method)方法构建RequestFactory对象:

static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    return new Builder(retrofit, method).build();
}

//Builder是RequestFactory的内部类
Builder(Retrofit retrofit, Method method) {
    this.retrofit = retrofit;
    this.method = method;
    this.methodAnnotations = method.getAnnotations();
    this.parameterTypes = method.getGenericParameterTypes();
    this.parameterAnnotationsArray = method.getParameterAnnotations();
}

RequestFactory build() {
    //遍历解析接口中所有请求方法上的注解和其中的参数,如@GET、@POST等
    for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
    }

    if (httpMethod == null) {
        throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
    }

    if (!hasBody) {
        if (isMultipart) {
            throw methodError(
                method,
                "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
        }
        if (isFormEncoded) {
            throw methodError(
                method,
                "FormUrlEncoded can only be specified on HTTP methods with "
                + "request body (e.g., @POST).");
        }
    }

    //下面解析接口中请求方法中参数的注解,如@Query、@Part等
    int parameterCount = parameterAnnotationsArray.length;
    parameterHandlers = new ParameterHandler<?>[parameterCount];
    for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
        //通过parseParameter解析请求方法中的参数和注解,下面还会说道
        parameterHandlers[p] =
            parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
    }

    if (relativeUrl == null && !gotUrl) {
        throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
    }
    if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
        throw methodError(method, "Non-body HTTP method cannot contain @Body.");
    }
    if (isFormEncoded && !gotField) {
        throw methodError(method, "Form-encoded method must contain at least one @Field.");
    }
    if (isMultipart && !gotPart) {
        throw methodError(method, "Multipart method must contain at least one @Part.");
    }

    //传入Builder对象创建RequestFactory对象
    return new RequestFactory(this);
}


//上面的parseParameter方法
private @Nullable ParameterHandler<?> parseParameter(
    int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
    
    ...

    if (result == null) {
        if (allowContinuation) {
            try {
                //下面通过传入的请求方法的参数的类是否是Continuation.class来判断请求方法是否是kotlin的挂起函数。通过反编译kotlin的挂起函数的字节码我们可以发现它为我们自动添加了一个Continuation对象,因此可以用来判断是否是kotlin挂起函数
                if (Utils.getRawType(parameterType) == Continuation.class) {
                    isKotlinSuspendFunction = true;
                    return null;
                }
            } catch (NoClassDefFoundError ignored) {
            }
        }
        throw parameterError(method, p, "No Retrofit annotation found.");
    }

    return result;
}

HttpServiceMethod.parseAnnotations(…)

这个方法在上面loadServiceMethod方法中用于创建一个ServiceMethod对象,HttpServiceMethod是ServiceMethod的子类。

static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
    Retrofit retrofit, Method method, RequestFactory requestFactory) {
    boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
    boolean continuationWantsResponse = false;
    boolean continuationBodyNullable = false;

    Annotation[] annotations = method.getAnnotations();
    Type adapterType;
    //下面代码主要是获取请求方法的返回类型,kotlin的挂起函数和普通函数获取方式有所不同
    if (isKotlinSuspendFunction) {
        Type[] parameterTypes = method.getGenericParameterTypes();
        Type responseType =
            Utils.getParameterLowerBound(
            0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
        if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
            responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
            continuationWantsResponse = true;
        } else {
        }

        adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
        annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
    } else {
        adapterType = method.getGenericReturnType();
    }

    //调用createCallAdapter来获取CallAdapter对象
    CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
    Type responseType = callAdapter.responseType();
    
    //...省略一些检查responseType的代码

    //遍历addConvertFactory方法中添加的转换器,并返回一个相应的转换器用来转换返回的数据
    Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType);

    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    //1.默认情况,不是kotlin挂起函数,直接返回CallAdapted对象
    if (!isKotlinSuspendFunction) {
        return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } 
    //下面两种是kotlin挂起函数的情况
    else if (continuationWantsResponse) {
        //2.返回值想要完整的Response
        return (HttpServiceMethod<ResponseT, ReturnT>)
            new SuspendForResponse<>(
            requestFactory,
            callFactory,
            responseConverter,
            (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
    } else {
        //3.只需要响应体
        return (HttpServiceMethod<ResponseT, ReturnT>)
            new SuspendForBody<>(
            requestFactory,
            callFactory,
            responseConverter,
            (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
            continuationBodyNullable);
    }
}

上面createCallAdapter方法会通过调用callAdapterFactories添加对象的get方法来获取CallAdapter对象。在Retrofit内部类Builder的build方法中会默认添加DefaultCallAdapterFactory对象,它的get方法如下:

@Override
public @Nullable CallAdapter<?, ?> get(
    Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
        return null;
    }
    if (!(returnType instanceof ParameterizedType)) {
        throw new IllegalArgumentException(
            "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
    }
    final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);

    final Executor executor =
        Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
        ? null
        : callbackExecutor;

    //创建一个CallAdapter对象
    return new CallAdapter<Object, Call<?>>() {
        @Override
        public Type responseType() {//接口中请求方法返回值的真实类型,也就是返回的Call对象泛型中的类型
            return responseType;
        }

        @Override
        public Call<Object> adapt(Call<Object> call) {
            //创建ExecutorCallbackCall对象
            return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
        }
    };
}

ExecutorCallbackCall是线程池和Call对象的封装类,这里的executor其实就是上面Platform类中创建的MainThreadExecutor,当调用ExecutorCallbackCall的enqueue方法时,其中会调用Call对象的enqueue方法通过OkHttp发起网络请求。数据返回后通过这个MainThreadExecutor将数据回调回主线程。

ServiceMethod.invoke(Object[] args)

这个方法在Retrofit.create方法中:loadServiceMethod(method).invoke(args),它的实现在HttpServiceMethod中。

@Override
final @Nullable ReturnT invoke(Object[] args) {
    Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
}

可以看到,它主要完成了两件事:

  • 通过多态创建Call对象
  • 调用adapt抽象方法

这个adapt方法的实现就在HttpServiceMethod的三个静态内部类CallAdaptedSuspendForResponseSuspendForBody

2.1 默认情况

即HttpServiceMethod.parseAnnotations(…)方法返回CallAdapted对象

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) {
        return callAdapter.adapt(call);
    }
}

//DefaultCallAdapterFactory的adapt方法,上面提到过:
@Override
public Call<Object> adapt(Call<Object> call) {
    //前面已经创建过ExecutorCallbackCall对象,这里直接返回Call对象
    return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}

当我们通过接口的动态代理调用请求方法拿到这里返回的Call对象后,一般会调用它的enqueue方法来进行异步请求,它会调用OkHttpCall的enqueue方法,其中会调用Call的enqueue方法:

//OkHttpCall.enqueue(final Callback<T> callback)方法中
//最终调用了RealCall的enqueue方法来进行请求,这就到了OkHttp的内容了
call.enqueue(
    new okhttp3.Callback() {
        @Override
        public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
            Response<T> response;
            try {
                //通过parseResponse方法解析返回的数据
                response = parseResponse(rawResponse);
            } catch (Throwable e) {
                throwIfFatal(e);
                callFailure(e);
                return;
            }

            try {
                //通过回调调用DefaultCallAdapterFactory中enqueue方法回调接口的onResponse实现,它会通过MainThreadExecutor将解析后的数据回调到主线程
                //也就是说,我们在使用call.enqueue(...)时其中的onResponse和onFailure方法在主线程执行
                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
            }
        }
    });

OkHttpCall.parseResponse(okhttp3.Response rawResponse)

Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    // Remove the body's source (the only stateful object) so we can pass the response along.
    rawResponse =
        rawResponse
        .newBuilder()
        .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
        .build();

    int code = rawResponse.code();
    if (code < 200 || code >= 300) {	//状态码不是2XX,请求不成功
        try {
            // Buffer the entire body to avoid future I/O.
            ResponseBody bufferedBody = Utils.buffer(rawBody);
            return Response.error(bufferedBody, rawResponse);
        } finally {
            rawBody.close();
        }
    }

    if (code == 204 || code == 205) {	//请求成功,但是返回内容为空
        rawBody.close();
        return Response.success(null, rawResponse);
    }

    ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
    try {
        //调用Converter对象的convert方法来转换数据,这就是HttpServiceMethod的parseAnnotations方法中创建的转换器
        T body = responseConverter.convert(catchingBody);
        return Response.success(body, rawResponse);
    } catch (RuntimeException e) {
        ...
    }
}

Converter是一个接口,它有很多实现类。如果我们在构建Retrofit对象时加入了GsonConverterFactory,其中会创建GsonResponseBodyConverter对象。

GsonResponseBodyConverter的convert方法:

@Override
public T convert(ResponseBody value) throws IOException {
    JsonReader jsonReader = gson.newJsonReader(value.charStream());
    try {
        //转换并返回转换后的数据
        T result = adapter.read(jsonReader);
        if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
            throw new JsonIOException("JSON document was not fully consumed.");
        }
        return result;
    } finally {
        value.close();
    }
}
2.2 kotlin挂起函数只需要响应体的情况

即HttpServiceMethod.parseAnnotations(…)方法返回SuspendForBody对象。SuspendForBody是HttpServiceMethod的静态内部类。

static final class SuspendForBody<ResponseT> extends HttpServiceMethod<ResponseT, Object> {
    private final CallAdapter<ResponseT, Call<ResponseT>> callAdapter;
    private final boolean isNullable;

    SuspendForBody(
        RequestFactory requestFactory,
        okhttp3.Call.Factory callFactory,
        Converter<ResponseBody, ResponseT> responseConverter,
        CallAdapter<ResponseT, Call<ResponseT>> callAdapter,
        boolean isNullable) {
        super(requestFactory, callFactory, responseConverter);
        this.callAdapter = callAdapter;
        this.isNullable = isNullable;
    }

    @Override
    protected Object adapt(Call<ResponseT> call, Object[] args) {
        call = callAdapter.adapt(call);

        Continuation<ResponseT> continuation = (Continuation<ResponseT>) args[args.length - 1];

        try {
            //根据泛型和返回值类型是否可空调用相应的方法,默认不可空,调用await方法
            return isNullable
                ? KotlinExtensions.awaitNullable(call, continuation)
                : KotlinExtensions.await(call, continuation);
        } catch (Exception e) {
            return KotlinExtensions.suspendAndThrow(e, continuation);
        }
    }
}

KotlinExtensions.await(call, continuation)

为什么下面Call的扩展函数没有参数,而上面java调用Kotlin的扩展函数时传入了两个参数了呢?

因为下面Call的await扩展函数实际上被编译为文件中和文件同名的类KotlinExtensions中的静态方法,因为Call的扩展函数中有Call对象的上下文,因此需要将Call对象作为第一个参数传入才能调用它的方法;

又因为下面kotlin扩展函数同时是一个挂起函数,所以又需要传入一个continuation对象

//KotlinExtensions.kt
suspend fun <T : Any> Call<T>.await(): T {
    return suspendCancellableCoroutine { continuation ->
                                        continuation.invokeOnCancellation {suspend fun <T : Any> Call<T>.await(): T {
  return suspendCancellableCoroutine { continuation ->
    continuation.invokeOnCancellation {
      cancel()
    }
    
    //调用Call的enqueue方法请求数据
    enqueue(object : Callback<T> {
      override fun onResponse(call: Call<T>, response: Response<T>) {
        if (response.isSuccessful) {	//响应码为2xx,请求和相应正常
          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)	//响应体为空,调用resumeWithException方法恢复协程并抛出一个异常
          } else {
            continuation.resume(body)	//正常恢复协程
          }
        } else {
          continuation.resumeWithException(HttpException(response))	//请求或相应异常
        }
      }

      override fun onFailure(call: Call<T>, t: Throwable) {
        continuation.resumeWithException(t)	//请求失败,可能因为网络等问题
      }
    })
  }
}
2.3 kotlin挂起函数返回值想要完整的Response的情况

和上面SuspendForBody很类似,只是SuspendForResponse的adapt方法会调用Call的awaitResponse扩展函数。它和await方法的区别仅在于onResponse方法中不会获取获取请求体,而是直接返回Response对象,这里不再赘述。

有了上面Retrofit对kotlin的支持,我们就可以这样优雅地实现网络请求,而不用再自己实现一个Call的await扩展函数了:

fun searchPlace() = withContext(Dispatchers.IO) {
    val retrofit = Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .baseUrl("xxx")
        .build()
        retrofit.create(PlaceService::class.java).searchPlaces("xxx")
}

上面创建retrofit的过程还可以进一步进行封装,这样就可以实现一行代码来进行网络请求了,具体实现就交给读者盆友们来完成了。

小结

Retrofit的简单使用和上面源码分析结合起来小结一哈:

  • 首先通过Retrofit的内部类Builder的build方法构建Retrofit对象
  • 再通过retrofit的create方法创建了请求接口的动态代理对象,这个动态代理对象的第三个参数是InvocationHandler接口的实例,当通过这个动态代理对象调用请求方法时就会回调这个接口的invoke方法。其中最重要的就是loadServiceMethod(method).invoke(args); 这行代码。
    • 这个loadServiceMethod方法中会先从缓存中获取ServiceMethod,没有的话再去创建一个HttpServiceMethod对象并将其存入缓存。它会对请求方法上面的请求方法注解、参数类型、返回值类型等进行解析,并判断该方法是否是kotlin挂起函数,根据请求方法返回HttpServiceMethod中不同的实现类对象。
    • invoke方法会调用ServiceMethod三个最终实现类的adapt方法。
      • 对于kotlin的挂起函数,调用adapt方法会直接调用Call对象相应的扩展函数,扩展函数内部会直接调用它的enqueue方法发起异步请求;
      • 对于普通的请求方法,invoke方法会创建一个ExecutorCallbackCall对象将OkHttpCall对象和MainThreadExecutor封装到其中,在我们显示调用Call的enqueue方法时会调用到ExecutorCallbackCall的enqueue方法,它通过调用OkHttpCall的enqueue方法发起网络请求,在回调中会在构建Retrofit对象时添加的Converter中寻找相应的转换器对返回的数据进行转换。而在ExecutorCallbackCall的enqueue方法中会通过MainThreadExecutor将数据回调到主线程。

参考资料

《Android进阶之光》

Retrofit加kotlin协程为何如此优雅

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值