Retrofit 源码分析

前言

现代Android开发中,Retrofit是主流的网络请求框架,内部封装OkHttp发起请求,也是声明式Http客户端,使用接口 + 注解的方式在接口中编写请求方法。

简单使用

先看下常规Retrofit的使用吧,也是通过入口API来看源码的一种好方法。

我们先来看不添加Convert转换器的方式,这种方式只能设置返回值中的泛型为ResponseBody,拿到的数据只能是Json字符串,而转换模型的操作需要我们自己做,当然如果是添加了转换器,则可以直接写模型的泛型了

  • 编写请求方法的接口
public interface WanAndroid {
    /**
     * Retrofit Call,获取首页文章列表,如果不添加转换器,则泛型只能是ResponseBody
     */
    @GET("article/list/{page}/json")
    Call<ResponseBody> getHomeArticleByCall(@Path("page") int page);
}
  • 创建Retroft实例
//创建Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
        //配置OkHttpClient
        .callFactory(new OkHttpClient.Builder().build())
        //配置基础Url
        .baseUrl("https://www.wanandroid.com")
        //开始创建
        .build();
//创建服务接口
WanAndroid wanAndroid = mRetrofit.create(WanAndroid.class);
  • 发起请求,没有添加转换器,需要自己做转换,代码太恶心了
wanAndroid.getHomeArticleByCall(page).enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        try {
            //解析Json,转换为模型
            String json = response.body().string();
            Gson gson = new Gson();
            Type type = new TypeToken<HttpModel<PageModel<HomeArticleModel>>>() {
            }.getType();
            HttpModel<PageModel<HomeArticleModel>> model = gson.fromJson(json, type);
            //请求成功
        } catch (IOException e) {
            e.printStackTrace();
            //请求失败
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable throwable) {
        ToastUtil.toast(getContext(), "请求失败:" + throwable.getMessage());
    }
});

开始分析

从简单使用来看,我们发现以下几点

  • Retrofit的实例创建,通过Builder构建者模式,通过链式编程进行Retrofit的配置,最后通过build()方法创建实例
  • 请求的方法,都放在接口上,通过Retrofit的create()方法,创建接口的实例
  • API接口的方法返回值为Call,它是Retrofit中的一个类

Retrofit实例创建

简单来讲,就是把Retrofit的构造方法私有,只能通过内部的Builder内部类的实例创建,所以我们对Retrofit的配置,都是配置到Retrofit内的Builder类后,再通过它的build方法,创建Retrofit实例。

public final class Retrofit {
    /**
     * OkHttpClient
     */
    final okhttp3.Call.Factory callFactory;
    /**
     * 基础Url
     */
    final HttpUrl baseUrl;
    /**
     * Converter转换器工厂列表
     */
    final List<Converter.Factory> converterFactories;
    /**
     * CallAdapter适配器工厂列表
     */
    final List<CallAdapter.Factory> callAdapterFactories;
    /**
     * 回调执行器
     */
    final @Nullable
    Executor callbackExecutor;
    /**
     * 是否创建接口实例时就校验接口的合法性,默认为false,在调用接口的方法时,才校验
     */
    final boolean validateEagerly;

    Retrofit(
            okhttp3.Call.Factory callFactory,
            HttpUrl baseUrl,
            List<Converter.Factory> converterFactories,
            List<CallAdapter.Factory> callAdapterFactories,
            @Nullable Executor callbackExecutor,
            boolean validateEagerly) {
        this.callFactory = callFactory;
        this.baseUrl = baseUrl;
        this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
        this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
        this.callbackExecutor = callbackExecutor;
        this.validateEagerly = validateEagerly;
    }
    /**
     * 使用Builder构建者模式
     */
    public static final class Builder {
        /**
         * 平台
         */
        private final Platform platform;
        /**
         * OkHttpClient
         */
        private @Nullable
        okhttp3.Call.Factory callFactory;
        /**
         * 基础路径
         */
        private @Nullable
        HttpUrl baseUrl;
        /**
         * 注册的Converter转换器工厂
         */
        private final List<Converter.Factory> converterFactories = new ArrayList<>();
        /**
         * 注册的CallAdapter适配器工厂
         */
        private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
        /**
         * 回调时使用的执行器
         */
        private @Nullable
        Executor callbackExecutor;
        /**
         * 是否马上检查API接口的合法性
         */
        private boolean validateEagerly;

        Builder(Platform platform) {
            this.platform = platform;
        }

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

        /**
         * 直接拷贝另外一个Retrofit实例的配置到Builder
         */
        Builder(Retrofit retrofit) {
            platform = Platform.get();
            callFactory = retrofit.callFactory;
            baseUrl = retrofit.baseUrl;

            // Do not add the default BuiltIntConverters and platform-aware converters added by build().
            for (int i = 1,
                 size = retrofit.converterFactories.size() - platform.defaultConverterFactoriesSize();
                 i < size;
                 i++) {
                converterFactories.add(retrofit.converterFactories.get(i));
            }

            // Do not add the default, platform-aware call adapters added by build().
            for (int i = 0,
                 size =
                 retrofit.callAdapterFactories.size() - platform.defaultCallAdapterFactoriesSize();
                 i < size;
                 i++) {
                callAdapterFactories.add(retrofit.callAdapterFactories.get(i));
            }

            callbackExecutor = retrofit.callbackExecutor;
            validateEagerly = retrofit.validateEagerly;
        }

        /**
         * 设置OkHttpClient
         */
        public Builder client(OkHttpClient client) {
            return callFactory(Objects.requireNonNull(client, "client == null"));
        }

        /**
         * 设置OkHttpClient
         */
        public Builder callFactory(okhttp3.Call.Factory factory) {
            this.callFactory = Objects.requireNonNull(factory, "factory == null");
            return this;
        }

        /**
         * 配置URL类型的基础Url
         */
        public Builder baseUrl(URL baseUrl) {
            Objects.requireNonNull(baseUrl, "baseUrl == null");
            return baseUrl(HttpUrl.get(baseUrl.toString()));
        }

        /**
         * 配置String类型基础Url
         */
        public Builder baseUrl(String baseUrl) {
            Objects.requireNonNull(baseUrl, "baseUrl == null");
            return baseUrl(HttpUrl.get(baseUrl));
        }

        /**
         * 配置HttpUrl类型基础Url
         */
        public Builder baseUrl(HttpUrl baseUrl) {
            Objects.requireNonNull(baseUrl, "baseUrl == null");
            List<String> pathSegments = baseUrl.pathSegments();
            if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
                throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
            }
            this.baseUrl = baseUrl;
            return this;
        }

        /**
         * 添加一个Converter工厂
         */
        public Builder addConverterFactory(Converter.Factory factory) {
            converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
            return this;
        }

        /**
         * 添加一个CallAdapter工厂
         */
        public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
            callAdapterFactories.add(Objects.requireNonNull(factory, "factory == null"));
            return this;
        }

        /**
         * 配置回调执行器
         */
        public Builder callbackExecutor(Executor executor) {
            this.callbackExecutor = Objects.requireNonNull(executor, "executor == null");
            return this;
        }

        /**
         * 返回注册的CallAdapter工厂
         */
        public List<CallAdapter.Factory> callAdapterFactories() {
            return this.callAdapterFactories;
        }

        /**
         * 返回注册的Converter工厂
         */
        public List<Converter.Factory> converterFactories() {
            return this.converterFactories;
        }

        /**
         * 配置是否迫切校验接口上的方法
         */
        public Builder validateEagerly(boolean validateEagerly) {
            this.validateEagerly = validateEagerly;
            return this;
        }

        /**
         * 构建一个Retrofit实例
         */
        public Retrofit build() {
            //必须设置基础路径
            if (baseUrl == null) {
                throw new IllegalStateException("Base URL required.");
            }

            okhttp3.Call.Factory callFactory = this.callFactory;
            //外部没有配置,创建默认配置的OkHttpClient
            if (callFactory == null) {
                callFactory = new OkHttpClient();
            }

            //外部没有配置,自动从平台中拿
            Executor callbackExecutor = this.callbackExecutor;
            if (callbackExecutor == null) {
                callbackExecutor = platform.defaultCallbackExecutor();
            }

            // Make a defensive copy of the adapters and add the default Call adapter.
            List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
            //默认添加一个CallAdapter工厂,支持Call类型的返回值
            callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

            // Make a defensive copy of the converters.
            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.
            //默认添加一个Converter工厂,支持返回值的泛型为RequestBody类型
            converterFactories.add(new BuiltInConverters());
            converterFactories.addAll(this.converterFactories);
            //从平台中拿Converter工厂,不同平台可以有不同的支持,如果支持Java8,则会添加一个Option类型的支持
            converterFactories.addAll(platform.defaultConverterFactories());
            //创建实例
            return new Retrofit(
                    callFactory,
                    baseUrl,
                    unmodifiableList(converterFactories),
                    unmodifiableList(callAdapterFactories),
                    callbackExecutor,
                    validateEagerly);
        }
    }
}
  • Platform类,请求响应回调在主线程的关键

在Builder的构造方法中,调用了Platform类的get方法,这个类是适配调用平台的,因为Retrofit的接口请求在子线程请求,而接口响应的回调方法,是可以在Android的主线程中回调的,这就肯定会涉及到Handler,而Retrofit也支持在鸿蒙上使用,这时就需要拓展Platfrom类来实现

可以看到,如果在Android平台运行,则返回的是Android实现类,该类复写了defaultCallbackExecutor()方法,返回MainThreadExecutor实例,这个Executor其实是线程池接口,只有一个execute()方法,MainThreadExecutor类复写了execute()方法,通过Handler把传进来的Runnable转发到主线程进行回调

class Platform {
    /**
     * 单例,查找到后,后续再调用不会再次查找
     */
    private static final Platform PLATFORM = findPlatform();

    /**
     * 获取Platform实例的方法
     */
    static Platform get() {
        return PLATFORM;
    }

    /**
     * 查找当前平台的实现
     */
    private static Platform findPlatform() {
        try {
            Class.forName("android.os.Build");
            //安卓
            if (Build.VERSION.SDK_INT != 0) {
                return new Android();
            }
        } catch (ClassNotFoundException ignored) {
            //ignored
        }
        //Java8
        return new Platform(true);
    }

    /**
     * 是否支持Java8
     */
    private final boolean hasJava8Types;
    private final @Nullable
    Constructor<Lookup> lookupConstructor;

    Platform(boolean hasJava8Types) {
        this.hasJava8Types = hasJava8Types;

        Constructor<Lookup> lookupConstructor = null;
        if (hasJava8Types) {
            try {
                // Because the service interface might not be public, we need to use a MethodHandle lookup
                // that ignores the visibility of the declaringClass.
                lookupConstructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
                lookupConstructor.setAccessible(true);
            } catch (NoClassDefFoundError ignored) {
                // Android API 24 or 25 where Lookup doesn't exist. Calling default methods on non-public
                // interfaces will fail, but there's nothing we can do about it.
            } catch (NoSuchMethodException ignored) {
                // Assume JDK 14+ which contains a fix that allows a regular lookup to succeed.
                // See https://bugs.openjdk.java.net/browse/JDK-8209005.
            }
        }
        this.lookupConstructor = lookupConstructor;
    }

    @Nullable
    Executor defaultCallbackExecutor() {
        return null;
    }

    List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
            @Nullable Executor callbackExecutor) {
        //默认的CallAdapterFactory,支持Call类型的返回值
        DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
        return hasJava8Types
                ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
                : singletonList(executorFactory);
    }

    int defaultCallAdapterFactoriesSize() {
        return hasJava8Types ? 2 : 1;
    }

    List<? extends Converter.Factory> defaultConverterFactories() {
        return hasJava8Types ? singletonList(OptionalConverterFactory.INSTANCE) : emptyList();
    }

    int defaultConverterFactoriesSize() {
        return hasJava8Types ? 1 : 0;
    }

    boolean isDefaultMethod(Method method) {
        return hasJava8Types && method.isDefault();
    }

    @Nullable
    Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object, Object... args)
            throws Throwable {
        Lookup lookup =
                lookupConstructor != null
                        ? lookupConstructor.newInstance(declaringClass, -1 /* trusted */)
                        : MethodHandles.lookup();
        return lookup.unreflectSpecial(method, declaringClass).bindTo(object).invokeWithArguments(args);
    }

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

        @Override
        public Executor defaultCallbackExecutor() {
            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());

            @Override
            public void execute(Runnable task) {
                handler.post(task);
            }
        }
    }
}

API接口实例创建

Http接口的实现,是通过create()方法创建的,内部使用的是JDK的动态代理,当我们调用代理类的方法时,会回调InvocationHandlerinvoke()方法

  • create(),动态代理接口的实现
/**
 * 传入一个API接口类的Class,动态代理该接口的实例
 */
@SuppressWarnings("unchecked")
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 {
                    //如果调用的是Object的方法,直接调用,不需要处理
                    if (method.getDeclaringClass() == Object.class) {
                        return method.invoke(this, args);
                    }
                    //没有参数,也用一个空数组
                    args = args != null ? args : emptyArgs;
                    //如果是default默认方法,直接调用
                    return platform.isDefaultMethod(method) ? platform.invokeDefaultMethod(method, service, proxy, args)
                            //普通方法,进行加载和解析,然后进行调用
                            : loadServiceMethod(method).invoke(args);
                }
            });
}
  • validateServiceInterface(),检查API接口的合法性
/**
 * 检查API接口Class
 */
private void validateServiceInterface(Class<?> service) {
    //传入的Class必须是接口类
    if (!service.isInterface()) {
        throw new IllegalArgumentException("API declarations must be interfaces.");
    }

    Deque<Class<?>> check = new ArrayDeque<>(1);
    check.add(service);
    while (!check.isEmpty()) {
        Class<?> candidate = check.removeFirst();
        if (candidate.getTypeParameters().length != 0) {
            StringBuilder message =
                    new StringBuilder("Type parameters are unsupported on ").append(candidate.getName());
            if (candidate != service) {
                message.append(" which is an interface of ").append(service.getName());
            }
            throw new IllegalArgumentException(message.toString());
        }
        Collections.addAll(check, candidate.getInterfaces());
    }
    //是否创建的时候就校验,默认为false,当调用接口方法时才校验,如果配置为true,则创建接口代理实现类时就校验
    if (validateEagerly) {
        Platform platform = Platform.get();
        //遍历接口上的方法
        for (Method method : service.getDeclaredMethods()) {
            //不检查default默认方法和静态方法
            if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
                loadServiceMethod(method);
            }
        }
    }
}
  • loadServiceMethod(),加载接口方法

InvocationHandler类的invoke()方法中,如果调用的是Object类的方法,直接调用,如果是Java8的默认方法,直接调用。最后就是普通的API方法,则调用loadServiceMethod(),这个方法的作用是解析API方法,并缓存到一个Map中,下次调用是直接复用的,最终是需要返回一个不为null的ServiceMethod实例,再调用它的invoke()执行方法调用

/**
 * 接口方法信息的缓存
 */
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();

/**
 * 加载接口方法
 */
ServiceMethod<?> loadServiceMethod(Method method) {
    //优先从缓存中取,取得到则返回,不需要每次调用都处理一次,浪费性能
    ServiceMethod<?> result = serviceMethodCache.get(method);
    if (result != null) {
        return result;
    }
    //Double Check + 同步锁,确保多线程调用时真的找不到缓存
    synchronized (serviceMethodCache) {
        result = serviceMethodCache.get(method);
        if (result == null) {
            //真的没有,解析方法上的注解
            result = ServiceMethod.parseAnnotations(this, method);
            //解析完,放到缓存
            serviceMethodCache.put(method, result);
        }
    }
    return result;
}
  • ServiceMethod.parseAnnotations,解析方法上的注解

loadServiceMethod ()中,如果没有命中缓存,则通过ServiceMethod.parseAnnotations(),解析方法注解,返回ServiceMethod实例,再缓存起来

其中,ServiceMethod是一个抽象类

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);
        }
        //返回值的泛型不能是Void类型
        if (returnType == void.class) {
            throw methodError(method, "Service methods cannot return void.");
        }
        //进行返回值适配和转换器
        return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
    }

    /**
     * 执行方法
     *
     * @param args 方法参数
     */
    abstract @Nullable
    T invoke(Object[] args);
}
  • RequestFactory.parseAnnotations(),解析接口上的请求方法的注解,以及方法形参上的注解,并把信息转换为RequestFactory实例

RequestFactory类也是一个Builder建造者模式,只是它是通过Builder类拆解Method对象,再通过build方法开始解析方法上的注解

注解分2种,分别是:方法级的注解方法形参上的注解方法级的注解@GET@POST这种作用于方法上的注解,而方法形参上的注解则是@Path@Field这种作用于形参上的注解

最后返回RequestFactory实例,最后调用HttpServiceMethod.parseAnnotations(),进行返回值适配和转换器

final class RequestFactory {
    /**
     * 解析方法上的注解
     */
    static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
        //把方法上的注解进行解析,并封装到RequestFactory类上
        return new Builder(retrofit, method).build();
    }
    
    static final class Builder {
        private static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*";
        private static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}");
        private static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM);

        final Retrofit retrofit;
        final Method method;
        final Annotation[] methodAnnotations;
        final Annotation[][] parameterAnnotationsArray;
        final Type[] parameterTypes;

        boolean gotField;
        boolean gotPart;
        boolean gotBody;
        boolean gotPath;
        boolean gotQuery;
        boolean gotQueryName;
        boolean gotQueryMap;
        boolean gotUrl;
        @Nullable
        String httpMethod;
        boolean hasBody;
        boolean isFormEncoded;
        boolean isMultipart;
        @Nullable
        String relativeUrl;
        @Nullable
        Headers headers;
        @Nullable
        MediaType contentType;
        @Nullable
        Set<String> relativeUrlParamNames;
        @Nullable
        ParameterHandler<?>[] parameterHandlers;

        /**
         * 把方法上的注解、返回值、方法形参上的注解保存
         */
        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() {
            //解析方法级的注解
            for (Annotation annotation : methodAnnotations) {
                parseMethodAnnotation(annotation);
            }

            //方法必须加上请求方式的注解,例如GET、POST
            if (httpMethod == null) {
                throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
            }

            //没有Body
            if (!hasBody) {
                //不能是文件请求,肯定是使用了@GET注解,必须要使用@POST
                if (isMultipart) {
                    throw methodError(
                            method,
                            "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
                }
                //不能是表单请求(表单请求是放在body上的)
                if (isFormEncoded) {
                    throw methodError(
                            method,
                            "FormUrlEncoded can only be specified on HTTP methods with "
                                    + "request body (e.g., @POST).");
                }
            }

            int parameterCount = parameterAnnotationsArray.length;
            parameterHandlers = new ParameterHandler<?>[parameterCount];
            for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
                //解析方法形参上的注解
                parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);
            }

            //不是相对路径的Url,必须添加@Url注解,指定完全路径的Url
            if (relativeUrl == null && !gotUrl) {
                throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
            }
            //没有请求体的请求方式,不能加@Body注解
            if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
                throw methodError(method, "Non-body HTTP method cannot contain @Body.");
            }
            //表单请求,必须要有一个参数要有@Field的参数
            if (isFormEncoded && !gotField) {
                throw methodError(method, "Form-encoded method must contain at least one @Field.");
            }
            //文件请求,必须要有一个参数要有@Field的参数
            if (isMultipart && !gotPart) {
                throw methodError(method, "Multipart method must contain at least one @Part.");
            }

            return new RequestFactory(this);
        }
    }
}
  • HttpServiceMethod.parseAnnotations,进行返回值适配和转换器

ServiceMethod是一个抽象类,通过ServiceMethod.parseAnnotations()静态方法,会返回其子类HttpServiceMethod,子类的创建则是通过HttpServiceMethod.parseAnnotations()创建

通过解析方法的返回值,调用createCallAdapter(),查找能适配返回值的CallAdapter,再调用createResponseConverter()查找对应的Converter转换器

发现,HttpServiceMethod也是一个抽象类,它在ServiceMethodinvoke()基础上,调用了一个adapt()抽象方法,其子类CallAdapted,复写了该方法,最终invoke()方法是通过CallAdapter来进行处理

/**
 * 一个把接口上的方法,转换为Http调用的ServiceMethod
 */
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
    private final RequestFactory requestFactory;
    private final okhttp3.Call.Factory callFactory;
    private final Converter<ResponseBody, ResponseT> responseConverter;

    HttpServiceMethod(
            RequestFactory requestFactory,
            okhttp3.Call.Factory callFactory,
            Converter<ResponseBody, ResponseT> responseConverter) {
        this.requestFactory = requestFactory;
        this.callFactory = callFactory;
        this.responseConverter = responseConverter;
    }

    /**
     * 解析方法上的注解
     */
    static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
            Retrofit retrofit, Method method, RequestFactory requestFactory) {
        //获取方法上的注解和返回值
        Annotation[] annotations = method.getAnnotations();
        Type adapterType = method.getGenericReturnType();

        //找到支持适配返回值类型的CallAdapter
        CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method, adapterType, annotations);
        Type responseType = callAdapter.responseType();
        //泛型不能为okhttp3的Response,你会不会是想要ResponseBody
        if (responseType == okhttp3.Response.class) {
            throw methodError(
                    method,
                    "'"
                            + getRawType(responseType).getName()
                            + "' is not a valid response body type. Did you mean ResponseBody?");
        }
        //Response必须要有泛型
        if (responseType == Response.class) {
            throw methodError(method, "Response must include generic type (e.g., Response<String>)");
        }
        // TODO support Unit for Kotlin?
        //顶层方法必须没有返回值,例如public void static main() {}
        if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
            throw methodError(method, "HEAD method must use Void as response type.");
        }

        //找到对应的转换器
        Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);

        okhttp3.Call.Factory callFactory = retrofit.callFactory;
        //创建支持适配工作的HttpServiceMethod,就是复写adapt()方法,并使用适配器进行转换
        return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    }

    /**
     * 找到支持适配返回值类型的CallAdapter
     */
    private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
            Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
        try {
            //noinspection unchecked
            return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
        } catch (RuntimeException e) { // Wide exception range because factories are user code.
            throw methodError(method, e, "Unable to create call adapter for %s", returnType);
        }
    }

    /**
     * 找到对应的转换器
     */
    private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
            Retrofit retrofit, Method method, Type responseType) {
        Annotation[] annotations = method.getAnnotations();
        try {
            return retrofit.responseBodyConverter(responseType, annotations);
        } catch (RuntimeException e) { // Wide exception range because factories are user code.
            throw methodError(method, e, "Unable to create converter for %s", responseType);
        }
    }

    /**
     * 执行方法调用
     */
    @Override
    final @Nullable
    ReturnT invoke(Object[] args) {
        //创建Call实例
        Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
        //进行适配后返回结果
        return adapt(call, args);
    }

    /**
     * 适配方法
     */
    protected abstract @Nullable
    ReturnT adapt(Call<ResponseT> call, Object[] args);

    /**
     * 支持进行适配的HttpServiceMethod子类
     */
    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) {
            //使用CallAdapter适配请求的返回值
            return callAdapter.adapt(call);
        }
    }
}

CallAdapter适配器

  • createCallAdapter,查找适配器

查找适配器的工作,发现是通过Retrofit实例callAdapter()方法,for循环查找注册的适配器,如果没有找到则抛异常,这实际上是策略模式的应用

public final class Retrofit {
    /**
     * 返回可以适配返回值类型的CallAdapter实例
     *
     * @throws IllegalArgumentException 如果没有找到,抛出异常
     */
    public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
        return nextCallAdapter(null, returnType, annotations);
    }

    /**
     * 返回可以适配返回值类型的CallAdapter实例
     *
     * @throws IllegalArgumentException 如果没有找到,抛出异常
     */
    public CallAdapter<?, ?> nextCallAdapter(
            @Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
        Objects.requireNonNull(returnType, "returnType == null");
        Objects.requireNonNull(annotations, "annotations == null");

        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;
            }
        }

        StringBuilder builder =
                new StringBuilder("Could not locate call adapter for ").append(returnType).append(".\n");
        if (skipPast != null) {
            builder.append("  Skipped:");
            for (int i = 0; i < start; i++) {
                builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
            }
            builder.append('\n');
        }
        builder.append("  Tried:");
        for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
            builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
        }
        throw new IllegalArgumentException(builder.toString());
    }
}
  • CallAdapter和CallAdapter.Factory

CallAdapter.FactoryCallAdapter的工厂类,每次发起请求,都是通过CallAdapter.Factory创建一个CallAdapter进行适配工作

主要方法是Factory.get(),创建CallAdapter,而CallAdapter的主要方法是adapt,该方法对Call类进行适配,以及responseType(),该方法返回该适配器能处理的返回值类型中的泛型Type

Retrofit构建时,就添加了一个默认的CallAdapter.Factory实例,它就是DefaultCallAdapterFactory,所以就是我们什么都不配置,默认找到的CallAdapter.Factory就是DefaultCallAdapterFactory

/**
 * 适配器,把Call中的泛型适配为返回值中的泛型
 */
public interface CallAdapter<R, T> {
    /**
     * 获取适配后的类型,例如{@code Call<Repo>},返回的是Repo的Type对象
     */
    Type responseType();

    /**
     * 把Call<R>适配为对应的返回值类型的泛型
     */
    T adapt(Call<R> call);

    /**
     * CallAdapter工厂,每次请求都会通过这个工厂生产CallAdapter
     */
    abstract class Factory {
        /**
         * 对方法进行适配,如果适配不了,返回null
         */
        public abstract @Nullable
        CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit);

        /**
         * 获取泛型的上界类型,例如{@Code Map<String, ? extends Runnable>},会返回Runnable
         */
        protected static Type getParameterUpperBound(int index, ParameterizedType type) {
            return Utils.getParameterUpperBound(index, type);
        }

        /**
         * 获取原始类型,例如{@code List<? extends Runnable>},会返回List
         */
        protected static Class<?> getRawType(Type type) {
            return Utils.getRawType(type);
        }
    }
}
  • DefaultCallAdapterFactory,默认的CallAdapter工厂

发现这个工厂类,在get()方法中,创建了一个CallAdapter的匿名内部类,responseType()返回了Call中的泛型Type,然后adapt()方法创建了一个ExecutorCallbackCall类,该类实现了Call接口

它其实是一个装饰器,包装了当前请求的Call类实例,并把enqueue()方法中的回调通过callbackExecutor做了调用包装,这个callbackExecutor就是Platform类中的MainThreadExecutor实例,所以就是这里来做回调的主线程回调的!

/**
 * 默认的CallAdapter工厂
 */
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
    /**
     * 回调执行器
     */
    private final @Nullable
    Executor callbackExecutor;

    DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
        this.callbackExecutor = callbackExecutor;
    }

    @Override
    public @Nullable
    CallAdapter<?, ?> get(
            Type returnType, Annotation[] annotations, Retrofit retrofit) {
        //返回值类型不是Call类型,不处理
        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>");
        }
        //获取Call中的泛型
        final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);

        //是否添加了SkipCallbackExecutor注解,如果添加了该注解,会不使用配置的callbackExecutor进行回调
        final Executor executor =
                Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
                        ? null
                        : callbackExecutor;

        //创建一个CallAdapter,把数据原封不动返回
        return new CallAdapter<Object, Call<?>>() {
            @Override
            public Type responseType() {
                return responseType;
            }

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

    /**
     * 装饰器,带回调执行器的Call,因为在OkHttpCall中的回调都是子线程回调的,这里可以再转到主线程进行回调
     */
    static final class ExecutorCallbackCall<T> implements Call<T> {
        final Executor callbackExecutor;
        final Call<T> delegate;

        ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
            this.callbackExecutor = callbackExecutor;
            this.delegate = delegate;
        }

        @Override
        public void enqueue(final Callback<T> callback) {
            Objects.requireNonNull(callback, "callback == null");
            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));
                }
            });
        }

        @Override
        public boolean isExecuted() {
            return delegate.isExecuted();
        }

        @Override
        public Response<T> execute() throws IOException {
            return delegate.execute();
        }

        @Override
        public void cancel() {
            delegate.cancel();
        }

        @Override
        public boolean isCanceled() {
            return delegate.isCanceled();
        }

        @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
        @Override
        public Call<T> clone() {
            return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
        }

        @Override
        public Request request() {
            return delegate.request();
        }

        @Override
        public Timeout timeout() {
            return delegate.timeout();
        }
    }
}

Converter转换器

CallAdapter查找完后,再查找Converter转换器,它的逻辑和上面查找CallAdapter很类似,都是在Retrofit的实例上找,Converter也有一个Factory工厂类

public final class Retrofit {
    /**
     * 获取支持返回值中的泛型为ResponseBody的Converter转换器
     */
    public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
        return nextResponseBodyConverter(null, type, annotations);
    }

    /**
     * 获取支持返回值中的泛型为ResponseBody的Converter转换器
     *
     * @param skipPast 可以指定跳过某个转换器
     */
    public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
            @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
        Objects.requireNonNull(type, "type == null");
        Objects.requireNonNull(annotations, "annotations == null");

        int start = converterFactories.indexOf(skipPast) + 1;
        for (int i = start, count = converterFactories.size(); i < count; i++) {
            Converter<ResponseBody, ?> converter =
                    converterFactories.get(i).responseBodyConverter(type, annotations, this);
            if (converter != null) {
                //noinspection unchecked
                return (Converter<ResponseBody, T>) converter;
            }
        }

        StringBuilder builder =
                new StringBuilder("Could not locate ResponseBody converter for ")
                        .append(type)
                        .append(".\n");
        if (skipPast != null) {
            builder.append("  Skipped:");
            for (int i = 0; i < start; i++) {
                builder.append("\n   * ").append(converterFactories.get(i).getClass().getName());
            }
            builder.append('\n');
        }
        builder.append("  Tried:");
        for (int i = start, count = converterFactories.size(); i < count; i++) {
            builder.append("\n   * ").append(converterFactories.get(i).getClass().getName());
        }
        throw new IllegalArgumentException(builder.toString());
    }
}
  • Converter.Factory,转换器工厂

同样,每次请求则创建都通过Factory创建一个Converter实例,Converter有2种

responseBodyConverter(),把ResponseBody转换为Type类型的模型(请求响应回来时调用),就是负责把接口响应的json数据,转换为对应的模型类

requestBodyConverter(),把Type模型转换为RequestBody,就是application/json这种类型的请求,把模型类转换为Json字符串,然后把Json字符串设置到RequestBody中

public interface Converter<F, T> {
    /**
     * 转换方法
     */
    @Nullable
    T convert(F value) throws IOException;

    /**
     * Converter转换器的工厂
     */
    abstract class Factory {
        /**
         * 把ResponseBody转换为Type类型的模型(请求响应回来时调用)
         */
        public @Nullable
        Converter<ResponseBody, ?> responseBodyConverter(
                Type type, Annotation[] annotations, Retrofit retrofit) {
            return null;
        }

        /**
         * 把Type模型转换为RequestBody(application/json请求前调用)
         */
        public @Nullable
        Converter<?, RequestBody> requestBodyConverter(
                Type type,
                Annotation[] parameterAnnotations,
                Annotation[] methodAnnotations,
                Retrofit retrofit) {
            return null;
        }

        /**
         * 把RequestBody转换为String类型的Converter
         */
        public @Nullable
        Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
            return null;
        }

        /**
         * 获取泛型的上界类型,例如{@Code Map<String, ? extends Runnable>},会返回Runnable
         */
        protected static Type getParameterUpperBound(int index, ParameterizedType type) {
            return Utils.getParameterUpperBound(index, type);
        }

        /**
         * 获取原始类型,例如{@code List<? extends Runnable>},会返回List
         */
        protected static Class<?> getRawType(Type type) {
            return Utils.getRawType(type);
        }
    }
}
  • BuiltInConverters,默认的转换器工厂

Retrofit实例创建中,也默认添加了一个转换器工厂,它就是BuiltInConverters

/**
 * 默认的Converter转换器工厂
 */
final class BuiltInConverters extends Converter.Factory {
    @Override
    public @Nullable
    Converter<ResponseBody, ?> responseBodyConverter(
            Type type, Annotation[] annotations, Retrofit retrofit) {
        //方法的返回值中的泛型,是ResponseBody时才可以使用
        if (type == ResponseBody.class) {
            return Utils.isAnnotationPresent(annotations, Streaming.class)
                    ? StreamingResponseBodyConverter.INSTANCE
                    : BufferingResponseBodyConverter.INSTANCE;
        }
        //泛型为Void
        if (type == Void.class) {
            return VoidResponseBodyConverter.INSTANCE;
        }
        return null;
    }

    @Override
    public @Nullable
    Converter<?, RequestBody> requestBodyConverter(
            Type type,
            Annotation[] parameterAnnotations,
            Annotation[] methodAnnotations,
            Retrofit retrofit) {
        //方法的形参有RequestBody时使用
        if (RequestBody.class.isAssignableFrom(Utils.getRawType(type))) {
            return RequestBodyConverter.INSTANCE;
        }
        return null;
    }

    /**
     * 返回值的泛型是Void时使用
     */
    static final class VoidResponseBodyConverter implements Converter<ResponseBody, Void> {
        static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();

        @Override
        public Void convert(ResponseBody value) {
            value.close();
            return null;
        }
    }

    /**
     * RequestBody转换器
     */
    static final class RequestBodyConverter implements Converter<RequestBody, RequestBody> {
        static final RequestBodyConverter INSTANCE = new RequestBodyConverter();

        @Override
        public RequestBody convert(RequestBody value) {
            //原封不动返回
            return value;
        }
    }

    static final class StreamingResponseBodyConverter
            implements Converter<ResponseBody, ResponseBody> {
        static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();

        @Override
        public ResponseBody convert(ResponseBody value) {
            return value;
        }
    }

    static final class BufferingResponseBodyConverter
            implements Converter<ResponseBody, ResponseBody> {
        static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();

        @Override
        public ResponseBody convert(ResponseBody value) throws IOException {
            try {
                // Buffer the entire body to avoid future I/O.
                return Utils.buffer(value);
            } finally {
                value.close();
            }
        }
    }

    /**
     * 返回值的泛型是String
     */
    static final class ToStringConverter implements Converter<Object, String> {
        static final ToStringConverter INSTANCE = new ToStringConverter();

        @Override
        public String convert(Object value) {
            return value.toString();
        }
    }
}

Call,发起请求

通过上面的步骤,解析API接口上的注解,查找CallAdapterConverter,只是loadServiceMethod()的处理过程,然后返回ServiceMethod实例,再调用它的invoke()方法进行调用,而ServiceMethod只是抽象类,具体实现在HttpServiceMethod

invoke(),返回一个Call实例,而它是一个接口,提供了一些请求方法,核心实现是OkHttpCall,还有一个ExecutorCallbackCall子类是做装饰器作用的,主要把回调方法通过平台的主线程调度器进行转发,实现主线程回调

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
    /**
     * 执行方法调用
     */
    @Override
    final @Nullable
    ReturnT invoke(Object[] args) {
        //创建Call实例
        Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
        //进行适配后返回结果
        return adapt(call, args);
    }
}
  • Call接口

主要请求方法有2个,execute同步请求,enqueue异步请求

/**
 * 请求封装,内部封装了OkHttp的Call
 */
public interface Call<T> extends Cloneable {
    /**
     * 同步请求
     */
    Response<T> execute() throws IOException;

    /**
     * 异步请求
     *
     * @param callback 回调
     */
    void enqueue(Callback<T> callback);

    /**
     * 是否已经被执行
     */
    boolean isExecuted();

    /**
     * 取消请求
     */
    void cancel();

    /**
     * 是否请求已经被取消
     */
    boolean isCanceled();

    /**
     * 克隆请求
     */
    Call<T> clone();

    /**
     * 获取请求的Request对象
     */
    Request request();

    /**
     * 获取请求的超时配置
     */
    Timeout timeout();
}
  • OkHttpCall

发现,OkHttpCall是对OkHttp的一层封装,做了一些响应码的处理,和Convert转换器的调用,OkHttpCall类是没有数据转换的,而Retrofit的Call类则是有Convert的支持,实现数据和模型的转换

/**
 * Call接口的实现,使用OkHttp进行请求,并进行结果回调的封装类,具有数据和模型的转换能力
 */
final class OkHttpCall<T> implements Call<T> {
    private final RequestFactory requestFactory;
    private final Object[] args;
    private final okhttp3.Call.Factory callFactory;
    private final Converter<ResponseBody, T> responseConverter;

    private volatile boolean canceled;

    @GuardedBy("this")
    private @Nullable
    okhttp3.Call rawCall;

    @GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
    private @Nullable
    Throwable creationFailure;

    @GuardedBy("this")
    private boolean executed;

    OkHttpCall(
            RequestFactory requestFactory,
            Object[] args,
            okhttp3.Call.Factory callFactory,
            Converter<ResponseBody, T> responseConverter) {
        this.requestFactory = requestFactory;
        this.args = args;
        this.callFactory = callFactory;
        this.responseConverter = responseConverter;
    }

    @SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state.
    @Override
    public OkHttpCall<T> clone() {
        return new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    }

    @Override
    public synchronized Request request() {
        try {
            return getRawCall().request();
        } catch (IOException e) {
            throw new RuntimeException("Unable to create request.", e);
        }
    }

    @Override
    public synchronized Timeout timeout() {
        try {
            return getRawCall().timeout();
        } catch (IOException e) {
            throw new RuntimeException("Unable to create call.", e);
        }
    }

    /**
     * 获取真实请求的实例,就是OkHttp的Call
     */
    @GuardedBy("this")
    private okhttp3.Call getRawCall() throws IOException {
        okhttp3.Call call = rawCall;
        //已经生成过了,直接返回
        if (call != null) {
            return call;
        }

        //不是第一次进行接口请求,并且发生错误,把错误再次抛出
        if (creationFailure != null) {
            if (creationFailure instanceof IOException) {
                throw (IOException) creationFailure;
            } else if (creationFailure instanceof RuntimeException) {
                throw (RuntimeException) creationFailure;
            } else {
                throw (Error) creationFailure;
            }
        }

        //创建OkHttp的Call对象
        try {
            return rawCall = createRawCall();
        } catch (RuntimeException | Error | IOException e) {
            throwIfFatal(e); // Do not assign a fatal error to creationFailure.
            creationFailure = e;
            throw e;
        }
    }

    @Override
    public void enqueue(final Callback<T> callback) {
        Objects.requireNonNull(callback, "callback == null");

        okhttp3.Call call;
        Throwable failure;

        synchronized (this) {
            //调用了一次enqueue()异步请求,不能再次调用
            if (executed) throw new IllegalStateException("Already executed.");
            executed = true;

            call = rawCall;
            failure = creationFailure;
            //创建OkHttp的Call对象
            if (call == null && failure == null) {
                try {
                    call = rawCall = createRawCall();
                } catch (Throwable t) {
                    throwIfFatal(t);
                    failure = creationFailure = t;
                }
            }
        }

        //失败了,回调外部
        if (failure != null) {
            callback.onFailure(this, failure);
            return;
        }

        //取消了任务,对真实请求做取消
        if (canceled) {
            call.cancel();
        }

        //发起异步请求
        call.enqueue(new okhttp3.Callback() {
            @Override
            public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
                Response<T> response;
                try {
                    //执行,并解析响应,统一返回Retrofit的Response对象
                    response = parseResponse(rawResponse);
                } catch (Throwable e) {
                    //解析失败,回调外部
                    throwIfFatal(e);
                    callFailure(e);
                    return;
                }
                //解析成功,回调外部
                try {
                    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
                }
            }
        });
    }

    @Override
    public synchronized boolean isExecuted() {
        return executed;
    }

    @Override
    public Response<T> execute() throws IOException {
        okhttp3.Call call;

        //同步请求
        synchronized (this) {
            if (executed) throw new IllegalStateException("Already executed.");
            executed = true;

            call = getRawCall();
        }

        //如果被取消,则取消任务
        if (canceled) {
            call.cancel();
        }

        //执行,并解析响应,统一返回Retrofit的Response对象
        return parseResponse(call.execute());
    }

    /**
     * 创建OkHttp3的Call对象
     */
    private okhttp3.Call createRawCall() throws IOException {
        okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
        //设置的OkHttpClient,不能返回null
        if (call == null) {
            throw new NullPointerException("Call.Factory returned null.");
        }
        return call;
    }

    /**
     * 执行,并解析响应,统一返回Retrofit的Response对象
     */
    Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
        ResponseBody rawBody = rawResponse.body();

        //移除真实请求的Body,方便传递
        rawResponse = rawResponse
                .newBuilder()
                .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
                .build();

        int code = rawResponse.code();
        //响应码不为正常的
        if (code < 200 || code >= 300) {
            try {
                ResponseBody bufferedBody = Utils.buffer(rawBody);
                //生成错误的Response对象
                return Response.error(bufferedBody, rawResponse);
            } finally {
                //关闭流
                rawBody.close();
            }
        }

        //204:请求成功了,但是没有相应体
        //205:请求成功了,重置表单,一般WebView才有
        if (code == 204 || code == 205) {
            rawBody.close();
            //由于没有响应体,直接返回成功
            return Response.success(null, rawResponse);
        }

        //包装一层,捕获异常
        ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
        try {
            //把ResponseBody转换具体的泛型模型类
            T body = responseConverter.convert(catchingBody);
            //返回Response
            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;
        }
    }

    @Override
    public void cancel() {
        canceled = true;

        okhttp3.Call call;
        synchronized (this) {
            call = rawCall;
        }
        //取消任务
        if (call != null) {
            call.cancel();
        }
    }

    @Override
    public boolean isCanceled() {
        if (canceled) {
            return true;
        }
        synchronized (this) {
            return rawCall != null && rawCall.isCanceled();
        }
    }

    static final class NoContentResponseBody extends ResponseBody {
        private final @Nullable
        MediaType contentType;
        private final long contentLength;

        NoContentResponseBody(@Nullable MediaType contentType, long contentLength) {
            this.contentType = contentType;
            this.contentLength = contentLength;
        }

        @Override
        public MediaType contentType() {
            return contentType;
        }

        @Override
        public long contentLength() {
            return contentLength;
        }

        @Override
        public BufferedSource source() {
            throw new IllegalStateException("Cannot read raw response body of a converted body.");
        }
    }

    /**
     * 装饰器,捕获异常的ResponseBody
     */
    static final class ExceptionCatchingResponseBody extends ResponseBody {
        private final ResponseBody delegate;
        private final BufferedSource delegateSource;
        @Nullable
        IOException thrownException;

        ExceptionCatchingResponseBody(ResponseBody delegate) {
            this.delegate = delegate;
            this.delegateSource = Okio.buffer(
                    new ForwardingSource(delegate.source()) {
                        @Override
                        public long read(Buffer sink, long byteCount) throws IOException {
                            try {
                                return super.read(sink, byteCount);
                            } catch (IOException e) {
                                thrownException = e;
                                throw e;
                            }
                        }
                    });
        }

        @Override
        public MediaType contentType() {
            return delegate.contentType();
        }

        @Override
        public long contentLength() {
            return delegate.contentLength();
        }

        @Override
        public BufferedSource source() {
            return delegateSource;
        }

        @Override
        public void close() {
            delegate.close();
        }

        void throwIfCaught() throws IOException {
            if (thrownException != null) {
                throw thrownException;
            }
        }
    }
}

Gson转换器

Converter转换器主要是做2种事情

  • Json上传类型的请求时,模型转Json
  • 接口响应时,Json转模型

而Gson就拥有这样的能力,所以Retrofit也提供Gson的转换器工厂,GsonConverterFactory

简单使用

Retrofit.Builder构建时,通过addConverterFactory,添加GsonConverterFactory转换器

//创建Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
        //配置OkHttpClient
        .callFactory(new OkHttpClient.Builder().build())
        //配置基础Url
        .baseUrl("https://www.wanandroid.com")
        //Gson转换器
        .addConverterFactory(GsonConverterFactory.create())
        //开始创建
        .build();
  • 添加一个请求方法,可以直接写模型的泛型
public interface WanAndroid {
    /**
     * Retrofit Call,获取首页文章列表,如果不添加转换器,则泛型只能是ResponseBody
     */
    @GET("article/list/{page}/json")
    Call<ResponseBody> getHomeArticleByCall(@Path("page") int page);

    /**
     * 添加了转换器,则可以直接用模型类的泛型,不需要ResponseBody了
     */
    @GET("article/list/{page}/json")
    Call<HttpModel<PageModel<HomeArticleModel>>> getHomeArticleByCallWithConverter(
            @Path("page") int page
    );
}
  • 调用,不需要自己做Json和模型的转换,优雅了许多
wanAndroid.getHomeArticleByCallWithConverter(page).enqueue(new Callback<HttpModel<PageModel<HomeArticleModel>>>() {
    @Override
    public void onResponse(Call<HttpModel<PageModel<HomeArticleModel>>> call,
                           Response<HttpModel<PageModel<HomeArticleModel>>> response) {
        //请求成功
    }

    @Override
    public void onFailure(Call<HttpModel<PageModel<HomeArticleModel>>> call, Throwable throwable) {
        //请求失败
    }
});

源码分析

  • 转换器工厂,实现Converter.Factory接口
/**
 * Gson转换器工厂
 */
public final class GsonConverterFactory extends Converter.Factory {
    /**
     * 创建方法,使用默认构造方法的Gson实例,JSON解码使用UTF-8
     */
    public static GsonConverterFactory create() {
        return create(new Gson());
    }

    /**
     * 指定Gson实例进行创建
     */
    @SuppressWarnings("ConstantConditions") // Guarding public API nullability.
    public static GsonConverterFactory create(Gson gson) {
        if (gson == null) throw new NullPointerException("gson == null");
        return new GsonConverterFactory(gson);
    }

    private final Gson gson;

    private GsonConverterFactory(Gson gson) {
        this.gson = gson;
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
                                                            Retrofit retrofit) {
        //ResponseBody响应数据转模型
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new GsonResponseBodyConverter<>(gson, adapter);
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type,
                                                          Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        //Json请求方式时,模型转Json
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new GsonRequestBodyConverter<>(gson, adapter);
    }
}
  • GsonRequestBodyConverter,Json请求方式时,模型转Json的转换器
/**
 * Json请求方式时,模型转Json的转换器
 */
final class GsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
  private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8");
  private static final Charset UTF_8 = Charset.forName("UTF-8");

  private final Gson gson;
  private final TypeAdapter<T> adapter;

  GsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
    this.gson = gson;
    this.adapter = adapter;
  }

  @Override public RequestBody convert(T value) throws IOException {
    Buffer buffer = new Buffer();
    Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
    JsonWriter jsonWriter = gson.newJsonWriter(writer);
    adapter.write(jsonWriter, value);
    jsonWriter.close();
    return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
  }
}
  • GsonResponseBodyConverter,ResponseBody响应数据转模型的转换器
/**
 * ResponseBody响应数据转模型的转换器
 */
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 {
      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();
    }
  }
}

总结

Retrofit中,使用了很多设计模式,例如:

  • 创建实例时使用Builder构建者模式,配置更加灵活
  • 代理模式,主要是JDK动态代理,让我们可以用接口,实现声明式Http请求调用
  • 责任链模式,配置多个CallAdapter和Converter,查找到最终匹配当前调用的方法的返回值,和Json和模型之间转换
  • 策略模式,不同平台的主线程执行器实现,通过Platform类拓展不同平台的子类
  • 装饰器模式,ExecutorCallbackCall,实现Call接口,对同样实现了Call接口的OkHttpCall进行装饰,实现enqueue()异步请求的回调在主线程中回调

既然Retrofit可以兼容多平台,而鸿蒙系统,也是基于Java,同样有主线程API,我们是不是可以拓展Retrofit的Platform类,实现鸿蒙上的子线程请求,主线程回调呢~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容