Retrofit 源碼分析

前言

現(xiàn)代Android開發(fā)中,Retrofit是主流的網(wǎng)絡(luò)請(qǐng)求框架,內(nèi)部封裝OkHttp發(fā)起請(qǐng)求,也是聲明式Http客戶端,使用接口 + 注解的方式在接口中編寫請(qǐng)求方法。

簡單使用

先看下常規(guī)Retrofit的使用吧,也是通過入口API來看源碼的一種好方法。

我們先來看不添加Convert轉(zhuǎn)換器的方式,這種方式只能設(shè)置返回值中的泛型為ResponseBody,拿到的數(shù)據(jù)只能是Json字符串,而轉(zhuǎn)換模型的操作需要我們自己做,當(dāng)然如果是添加了轉(zhuǎn)換器,則可以直接寫模型的泛型了

  • 編寫請(qǐng)求方法的接口
public interface WanAndroid {
    /**
     * Retrofit Call,獲取首頁文章列表,如果不添加轉(zhuǎn)換器,則泛型只能是ResponseBody
     */
    @GET("article/list/{page}/json")
    Call<ResponseBody> getHomeArticleByCall(@Path("page") int page);
}
  • 創(chuàng)建Retroft實(shí)例
//創(chuàng)建Retrofit實(shí)例
Retrofit retrofit = new Retrofit.Builder()
        //配置OkHttpClient
        .callFactory(new OkHttpClient.Builder().build())
        //配置基礎(chǔ)Url
        .baseUrl("https://www.wanandroid.com")
        //開始創(chuàng)建
        .build();
//創(chuàng)建服務(wù)接口
WanAndroid wanAndroid = mRetrofit.create(WanAndroid.class);
  • 發(fā)起請(qǐng)求,沒有添加轉(zhuǎn)換器,需要自己做轉(zhuǎn)換,代碼太惡心了
wanAndroid.getHomeArticleByCall(page).enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        try {
            //解析Json,轉(zhuǎn)換為模型
            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);
            //請(qǐng)求成功
        } catch (IOException e) {
            e.printStackTrace();
            //請(qǐng)求失敗
        }
    }

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

開始分析

從簡單使用來看,我們發(fā)現(xiàn)以下幾點(diǎn)

  • Retrofit的實(shí)例創(chuàng)建,通過Builder構(gòu)建者模式,通過鏈?zhǔn)骄幊踢M(jìn)行Retrofit的配置,最后通過build()方法創(chuàng)建實(shí)例
  • 請(qǐng)求的方法,都放在接口上,通過Retrofit的create()方法,創(chuàng)建接口的實(shí)例
  • API接口的方法返回值為Call,它是Retrofit中的一個(gè)類

Retrofit實(shí)例創(chuàng)建

簡單來講,就是把Retrofit的構(gòu)造方法私有,只能通過內(nèi)部的Builder內(nèi)部類的實(shí)例創(chuàng)建,所以我們對(duì)Retrofit的配置,都是配置到Retrofit內(nèi)的Builder類后,再通過它的build方法,創(chuàng)建Retrofit實(shí)例。

public final class Retrofit {
    /**
     * OkHttpClient
     */
    final okhttp3.Call.Factory callFactory;
    /**
     * 基礎(chǔ)Url
     */
    final HttpUrl baseUrl;
    /**
     * Converter轉(zhuǎn)換器工廠列表
     */
    final List<Converter.Factory> converterFactories;
    /**
     * CallAdapter適配器工廠列表
     */
    final List<CallAdapter.Factory> callAdapterFactories;
    /**
     * 回調(diào)執(zhí)行器
     */
    final @Nullable
    Executor callbackExecutor;
    /**
     * 是否創(chuàng)建接口實(shí)例時(shí)就校驗(yàn)接口的合法性,默認(rèn)為false,在調(diào)用接口的方法時(shí),才校驗(yàn)
     */
    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構(gòu)建者模式
     */
    public static final class Builder {
        /**
         * 平臺(tái)
         */
        private final Platform platform;
        /**
         * OkHttpClient
         */
        private @Nullable
        okhttp3.Call.Factory callFactory;
        /**
         * 基礎(chǔ)路徑
         */
        private @Nullable
        HttpUrl baseUrl;
        /**
         * 注冊的Converter轉(zhuǎn)換器工廠
         */
        private final List<Converter.Factory> converterFactories = new ArrayList<>();
        /**
         * 注冊的CallAdapter適配器工廠
         */
        private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
        /**
         * 回調(diào)時(shí)使用的執(zhí)行器
         */
        private @Nullable
        Executor callbackExecutor;
        /**
         * 是否馬上檢查API接口的合法性
         */
        private boolean validateEagerly;

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

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

        /**
         * 直接拷貝另外一個(gè)Retrofit實(shí)例的配置到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;
        }

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

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

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

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

        /**
         * 配置HttpUrl類型基礎(chǔ)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;
        }

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

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

        /**
         * 配置回調(diào)執(zhí)行器
         */
        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;
        }

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

        /**
         * 構(gòu)建一個(gè)Retrofit實(shí)例
         */
        public Retrofit build() {
            //必須設(shè)置基礎(chǔ)路徑
            if (baseUrl == null) {
                throw new IllegalStateException("Base URL required.");
            }

            okhttp3.Call.Factory callFactory = this.callFactory;
            //外部沒有配置,創(chuàng)建默認(rèn)配置的OkHttpClient
            if (callFactory == null) {
                callFactory = new OkHttpClient();
            }

            //外部沒有配置,自動(dòng)從平臺(tái)中拿
            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);
            //默認(rèn)添加一個(gè)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.
            //默認(rèn)添加一個(gè)Converter工廠,支持返回值的泛型為RequestBody類型
            converterFactories.add(new BuiltInConverters());
            converterFactories.addAll(this.converterFactories);
            //從平臺(tái)中拿Converter工廠,不同平臺(tái)可以有不同的支持,如果支持Java8,則會(huì)添加一個(gè)Option類型的支持
            converterFactories.addAll(platform.defaultConverterFactories());
            //創(chuàng)建實(shí)例
            return new Retrofit(
                    callFactory,
                    baseUrl,
                    unmodifiableList(converterFactories),
                    unmodifiableList(callAdapterFactories),
                    callbackExecutor,
                    validateEagerly);
        }
    }
}
  • Platform類,請(qǐng)求響應(yīng)回調(diào)在主線程的關(guān)鍵

在Builder的構(gòu)造方法中,調(diào)用了Platform類的get方法,這個(gè)類是適配調(diào)用平臺(tái)的,因?yàn)镽etrofit的接口請(qǐng)求在子線程請(qǐng)求,而接口響應(yīng)的回調(diào)方法,是可以在Android的主線程中回調(diào)的,這就肯定會(huì)涉及到Handler,而Retrofit也支持在鴻蒙上使用,這時(shí)就需要拓展Platfrom類來實(shí)現(xiàn)

可以看到,如果在Android平臺(tái)運(yùn)行,則返回的是Android實(shí)現(xiàn)類,該類復(fù)寫了defaultCallbackExecutor()方法,返回MainThreadExecutor實(shí)例,這個(gè)Executor其實(shí)是線程池接口,只有一個(gè)execute()方法,MainThreadExecutor類復(fù)寫了execute()方法,通過Handler把傳進(jìn)來的Runnable轉(zhuǎn)發(fā)到主線程進(jìn)行回調(diào)

class Platform {
    /**
     * 單例,查找到后,后續(xù)再調(diào)用不會(huì)再次查找
     */
    private static final Platform PLATFORM = findPlatform();

    /**
     * 獲取Platform實(shí)例的方法
     */
    static Platform get() {
        return PLATFORM;
    }

    /**
     * 查找當(dāng)前平臺(tái)的實(shí)現(xiàn)
     */
    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) {
        //默認(rèn)的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);
        }

        /**
         * 安卓主線程執(zhí)行器
         */
        static final class MainThreadExecutor implements Executor {
            private final Handler handler = new Handler(Looper.getMainLooper());

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

API接口實(shí)例創(chuàng)建

Http接口的實(shí)現(xiàn),是通過create()方法創(chuàng)建的,內(nèi)部使用的是JDK的動(dòng)態(tài)代理,當(dāng)我們調(diào)用代理類的方法時(shí),會(huì)回調(diào)InvocationHandlerinvoke()方法

  • create(),動(dòng)態(tài)代理接口的實(shí)現(xiàn)
/**
 * 傳入一個(gè)API接口類的Class,動(dòng)態(tài)代理該接口的實(shí)例
 */
@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 {
                    //如果調(diào)用的是Object的方法,直接調(diào)用,不需要處理
                    if (method.getDeclaringClass() == Object.class) {
                        return method.invoke(this, args);
                    }
                    //沒有參數(shù),也用一個(gè)空數(shù)組
                    args = args != null ? args : emptyArgs;
                    //如果是default默認(rèn)方法,直接調(diào)用
                    return platform.isDefaultMethod(method) ? platform.invokeDefaultMethod(method, service, proxy, args)
                            //普通方法,進(jìn)行加載和解析,然后進(jìn)行調(diào)用
                            : 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());
    }
    //是否創(chuàng)建的時(shí)候就校驗(yàn),默認(rèn)為false,當(dāng)調(diào)用接口方法時(shí)才校驗(yàn),如果配置為true,則創(chuàng)建接口代理實(shí)現(xiàn)類時(shí)就校驗(yàn)
    if (validateEagerly) {
        Platform platform = Platform.get();
        //遍歷接口上的方法
        for (Method method : service.getDeclaredMethods()) {
            //不檢查default默認(rèn)方法和靜態(tài)方法
            if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
                loadServiceMethod(method);
            }
        }
    }
}
  • loadServiceMethod(),加載接口方法

InvocationHandler類的invoke()方法中,如果調(diào)用的是Object類的方法,直接調(diào)用,如果是Java8的默認(rèn)方法,直接調(diào)用。最后就是普通的API方法,則調(diào)用loadServiceMethod(),這個(gè)方法的作用是解析API方法,并緩存到一個(gè)Map中,下次調(diào)用是直接復(fù)用的,最終是需要返回一個(gè)不為null的ServiceMethod實(shí)例,再調(diào)用它的invoke()執(zhí)行方法調(diào)用

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

/**
 * 加載接口方法
 */
ServiceMethod<?> loadServiceMethod(Method method) {
    //優(yōu)先從緩存中取,取得到則返回,不需要每次調(diào)用都處理一次,浪費(fèi)性能
    ServiceMethod<?> result = serviceMethodCache.get(method);
    if (result != null) {
        return result;
    }
    //Double Check + 同步鎖,確保多線程調(diào)用時(shí)真的找不到緩存
    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實(shí)例,再緩存起來

其中,ServiceMethod是一個(gè)抽象類

abstract class ServiceMethod<T> {
    /**
     * 解析注解
     */
    static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
        //解析接口上的請(qǐng)求方法的注解,以及方法形參上的注解,并把信息轉(zhuǎn)換為RequestFactory實(shí)例
        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.");
        }
        //進(jìn)行返回值適配和轉(zhuǎn)換器
        return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
    }

    /**
     * 執(zhí)行方法
     *
     * @param args 方法參數(shù)
     */
    abstract @Nullable
    T invoke(Object[] args);
}
  • RequestFactory.parseAnnotations(),解析接口上的請(qǐng)求方法的注解,以及方法形參上的注解,并把信息轉(zhuǎn)換為RequestFactory實(shí)例

RequestFactory類也是一個(gè)Builder建造者模式,只是它是通過Builder類拆解Method對(duì)象,再通過build方法開始解析方法上的注解

注解分2種,分別是:方法級(jí)的注解方法形參上的注解,方法級(jí)的注解@GET、@POST這種作用于方法上的注解,而方法形參上的注解則是@Path、@Field這種作用于形參上的注解

最后返回RequestFactory實(shí)例,最后調(diào)用HttpServiceMethod.parseAnnotations(),進(jìn)行返回值適配和轉(zhuǎn)換器

final class RequestFactory {
    /**
     * 解析方法上的注解
     */
    static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
        //把方法上的注解進(jìn)行解析,并封裝到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() {
            //解析方法級(jí)的注解
            for (Annotation annotation : methodAnnotations) {
                parseMethodAnnotation(annotation);
            }

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

            //沒有Body
            if (!hasBody) {
                //不能是文件請(qǐng)求,肯定是使用了@GET注解,必須要使用@POST
                if (isMultipart) {
                    throw methodError(
                            method,
                            "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
                }
                //不能是表單請(qǐng)求(表單請(qǐng)求是放在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]);
            }

            //不是相對(duì)路徑的Url,必須添加@Url注解,指定完全路徑的Url
            if (relativeUrl == null && !gotUrl) {
                throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
            }
            //沒有請(qǐng)求體的請(qǐng)求方式,不能加@Body注解
            if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
                throw methodError(method, "Non-body HTTP method cannot contain @Body.");
            }
            //表單請(qǐng)求,必須要有一個(gè)參數(shù)要有@Field的參數(shù)
            if (isFormEncoded && !gotField) {
                throw methodError(method, "Form-encoded method must contain at least one @Field.");
            }
            //文件請(qǐng)求,必須要有一個(gè)參數(shù)要有@Field的參數(shù)
            if (isMultipart && !gotPart) {
                throw methodError(method, "Multipart method must contain at least one @Part.");
            }

            return new RequestFactory(this);
        }
    }
}
  • HttpServiceMethod.parseAnnotations,進(jìn)行返回值適配和轉(zhuǎn)換器

ServiceMethod是一個(gè)抽象類,通過ServiceMethod.parseAnnotations()靜態(tài)方法,會(huì)返回其子類HttpServiceMethod,子類的創(chuàng)建則是通過HttpServiceMethod.parseAnnotations()創(chuàng)建

通過解析方法的返回值,調(diào)用createCallAdapter(),查找能適配返回值的CallAdapter,再調(diào)用createResponseConverter()查找對(duì)應(yīng)的Converter轉(zhuǎn)換器

發(fā)現(xiàn),HttpServiceMethod也是一個(gè)抽象類,它在ServiceMethodinvoke()基礎(chǔ)上,調(diào)用了一個(gè)adapt()抽象方法,其子類CallAdapted,復(fù)寫了該方法,最終invoke()方法是通過CallAdapter來進(jìn)行處理

/**
 * 一個(gè)把接口上的方法,轉(zhuǎn)換為Http調(diào)用的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,你會(huì)不會(huì)是想要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.");
        }

        //找到對(duì)應(yīng)的轉(zhuǎn)換器
        Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);

        okhttp3.Call.Factory callFactory = retrofit.callFactory;
        //創(chuàng)建支持適配工作的HttpServiceMethod,就是復(fù)寫adapt()方法,并使用適配器進(jìn)行轉(zhuǎn)換
        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);
        }
    }

    /**
     * 找到對(duì)應(yīng)的轉(zhuǎn)換器
     */
    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);
        }
    }

    /**
     * 執(zhí)行方法調(diào)用
     */
    @Override
    final @Nullable
    ReturnT invoke(Object[] args) {
        //創(chuàng)建Call實(shí)例
        Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
        //進(jìn)行適配后返回結(jié)果
        return adapt(call, args);
    }

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

    /**
     * 支持進(jìn)行適配的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適配請(qǐng)求的返回值
            return callAdapter.adapt(call);
        }
    }
}

CallAdapter適配器

  • createCallAdapter,查找適配器

查找適配器的工作,發(fā)現(xiàn)是通過Retrofit實(shí)例callAdapter()方法,for循環(huán)查找注冊的適配器,如果沒有找到則拋異常,這實(shí)際上是策略模式的應(yīng)用

public final class Retrofit {
    /**
     * 返回可以適配返回值類型的CallAdapter實(shí)例
     *
     * @throws IllegalArgumentException 如果沒有找到,拋出異常
     */
    public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
        return nextCallAdapter(null, returnType, annotations);
    }

    /**
     * 返回可以適配返回值類型的CallAdapter實(shí)例
     *
     * @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的工廠類,每次發(fā)起請(qǐng)求,都是通過CallAdapter.Factory創(chuàng)建一個(gè)CallAdapter進(jìn)行適配工作

主要方法是Factory.get(),創(chuàng)建CallAdapter,而CallAdapter的主要方法是adapt,該方法對(duì)Call類進(jìn)行適配,以及responseType(),該方法返回該適配器能處理的返回值類型中的泛型Type

Retrofit構(gòu)建時(shí),就添加了一個(gè)默認(rèn)的CallAdapter.Factory實(shí)例,它就是DefaultCallAdapterFactory,所以就是我們什么都不配置,默認(rèn)找到的CallAdapter.Factory就是DefaultCallAdapterFactory

/**
 * 適配器,把Call中的泛型適配為返回值中的泛型
 */
public interface CallAdapter<R, T> {
    /**
     * 獲取適配后的類型,例如{@code Call<Repo>},返回的是Repo的Type對(duì)象
     */
    Type responseType();

    /**
     * 把Call<R>適配為對(duì)應(yīng)的返回值類型的泛型
     */
    T adapt(Call<R> call);

    /**
     * CallAdapter工廠,每次請(qǐng)求都會(huì)通過這個(gè)工廠生產(chǎn)CallAdapter
     */
    abstract class Factory {
        /**
         * 對(duì)方法進(jìn)行適配,如果適配不了,返回null
         */
        public abstract @Nullable
        CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit);

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

        /**
         * 獲取原始類型,例如{@code List<? extends Runnable>},會(huì)返回List
         */
        protected static Class<?> getRawType(Type type) {
            return Utils.getRawType(type);
        }
    }
}
  • DefaultCallAdapterFactory,默認(rèn)的CallAdapter工廠

發(fā)現(xiàn)這個(gè)工廠類,在get()方法中,創(chuàng)建了一個(gè)CallAdapter的匿名內(nèi)部類,responseType()返回了Call中的泛型Type,然后adapt()方法創(chuàng)建了一個(gè)ExecutorCallbackCall類,該類實(shí)現(xiàn)了Call接口

它其實(shí)是一個(gè)裝飾器,包裝了當(dāng)前請(qǐng)求的Call類實(shí)例,并把enqueue()方法中的回調(diào)通過callbackExecutor做了調(diào)用包裝,這個(gè)callbackExecutor就是Platform類中的MainThreadExecutor實(shí)例,所以就是這里來做回調(diào)的主線程回調(diào)的!

/**
 * 默認(rèn)的CallAdapter工廠
 */
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
    /**
     * 回調(diào)執(zhí)行器
     */
    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注解,如果添加了該注解,會(huì)不使用配置的callbackExecutor進(jìn)行回調(diào)
        final Executor executor =
                Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
                        ? null
                        : callbackExecutor;

        //創(chuàng)建一個(gè)CallAdapter,把數(shù)據(jù)原封不動(dòng)返回
        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);
            }
        };
    }

    /**
     * 裝飾器,帶回調(diào)執(zhí)行器的Call,因?yàn)樵贠kHttpCall中的回調(diào)都是子線程回調(diào)的,這里可以再轉(zhuǎn)到主線程進(jìn)行回調(diào)
     */
    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轉(zhuǎn)換器

CallAdapter查找完后,再查找Converter轉(zhuǎn)換器,它的邏輯和上面查找CallAdapter很類似,都是在Retrofit的實(shí)例上找,Converter也有一個(gè)Factory工廠類

public final class Retrofit {
    /**
     * 獲取支持返回值中的泛型為ResponseBody的Converter轉(zhuǎn)換器
     */
    public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
        return nextResponseBodyConverter(null, type, annotations);
    }

    /**
     * 獲取支持返回值中的泛型為ResponseBody的Converter轉(zhuǎn)換器
     *
     * @param skipPast 可以指定跳過某個(gè)轉(zhuǎn)換器
     */
    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,轉(zhuǎn)換器工廠

同樣,每次請(qǐng)求則創(chuàng)建都通過Factory創(chuàng)建一個(gè)Converter實(shí)例,Converter有2種

responseBodyConverter(),把ResponseBody轉(zhuǎn)換為Type類型的模型(請(qǐng)求響應(yīng)回來時(shí)調(diào)用),就是負(fù)責(zé)把接口響應(yīng)的json數(shù)據(jù),轉(zhuǎn)換為對(duì)應(yīng)的模型類

requestBodyConverter(),把Type模型轉(zhuǎn)換為RequestBody,就是application/json這種類型的請(qǐng)求,把模型類轉(zhuǎn)換為Json字符串,然后把Json字符串設(shè)置到RequestBody中

public interface Converter<F, T> {
    /**
     * 轉(zhuǎn)換方法
     */
    @Nullable
    T convert(F value) throws IOException;

    /**
     * Converter轉(zhuǎn)換器的工廠
     */
    abstract class Factory {
        /**
         * 把ResponseBody轉(zhuǎn)換為Type類型的模型(請(qǐng)求響應(yīng)回來時(shí)調(diào)用)
         */
        public @Nullable
        Converter<ResponseBody, ?> responseBodyConverter(
                Type type, Annotation[] annotations, Retrofit retrofit) {
            return null;
        }

        /**
         * 把Type模型轉(zhuǎn)換為RequestBody(application/json請(qǐng)求前調(diào)用)
         */
        public @Nullable
        Converter<?, RequestBody> requestBodyConverter(
                Type type,
                Annotation[] parameterAnnotations,
                Annotation[] methodAnnotations,
                Retrofit retrofit) {
            return null;
        }

        /**
         * 把RequestBody轉(zhuǎn)換為String類型的Converter
         */
        public @Nullable
        Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
            return null;
        }

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

        /**
         * 獲取原始類型,例如{@code List<? extends Runnable>},會(huì)返回List
         */
        protected static Class<?> getRawType(Type type) {
            return Utils.getRawType(type);
        }
    }
}
  • BuiltInConverters,默認(rèn)的轉(zhuǎn)換器工廠

Retrofit實(shí)例創(chuàng)建中,也默認(rèn)添加了一個(gè)轉(zhuǎn)換器工廠,它就是BuiltInConverters

/**
 * 默認(rèn)的Converter轉(zhuǎn)換器工廠
 */
final class BuiltInConverters extends Converter.Factory {
    @Override
    public @Nullable
    Converter<ResponseBody, ?> responseBodyConverter(
            Type type, Annotation[] annotations, Retrofit retrofit) {
        //方法的返回值中的泛型,是ResponseBody時(shí)才可以使用
        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時(shí)使用
        if (RequestBody.class.isAssignableFrom(Utils.getRawType(type))) {
            return RequestBodyConverter.INSTANCE;
        }
        return null;
    }

    /**
     * 返回值的泛型是Void時(shí)使用
     */
    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轉(zhuǎn)換器
     */
    static final class RequestBodyConverter implements Converter<RequestBody, RequestBody> {
        static final RequestBodyConverter INSTANCE = new RequestBodyConverter();

        @Override
        public RequestBody convert(RequestBody value) {
            //原封不動(dòng)返回
            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,發(fā)起請(qǐng)求

通過上面的步驟,解析API接口上的注解,查找CallAdapterConverter,只是loadServiceMethod()的處理過程,然后返回ServiceMethod實(shí)例,再調(diào)用它的invoke()方法進(jìn)行調(diào)用,而ServiceMethod只是抽象類,具體實(shí)現(xiàn)在HttpServiceMethod

invoke(),返回一個(gè)Call實(shí)例,而它是一個(gè)接口,提供了一些請(qǐng)求方法,核心實(shí)現(xiàn)是OkHttpCall,還有一個(gè)ExecutorCallbackCall子類是做裝飾器作用的,主要把回調(diào)方法通過平臺(tái)的主線程調(diào)度器進(jìn)行轉(zhuǎn)發(fā),實(shí)現(xiàn)主線程回調(diào)

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
    /**
     * 執(zhí)行方法調(diào)用
     */
    @Override
    final @Nullable
    ReturnT invoke(Object[] args) {
        //創(chuàng)建Call實(shí)例
        Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
        //進(jìn)行適配后返回結(jié)果
        return adapt(call, args);
    }
}
  • Call接口

主要請(qǐng)求方法有2個(gè),execute同步請(qǐng)求,enqueue異步請(qǐng)求

/**
 * 請(qǐng)求封裝,內(nèi)部封裝了OkHttp的Call
 */
public interface Call<T> extends Cloneable {
    /**
     * 同步請(qǐng)求
     */
    Response<T> execute() throws IOException;

    /**
     * 異步請(qǐng)求
     *
     * @param callback 回調(diào)
     */
    void enqueue(Callback<T> callback);

    /**
     * 是否已經(jīng)被執(zhí)行
     */
    boolean isExecuted();

    /**
     * 取消請(qǐng)求
     */
    void cancel();

    /**
     * 是否請(qǐng)求已經(jīng)被取消
     */
    boolean isCanceled();

    /**
     * 克隆請(qǐng)求
     */
    Call<T> clone();

    /**
     * 獲取請(qǐng)求的Request對(duì)象
     */
    Request request();

    /**
     * 獲取請(qǐng)求的超時(shí)配置
     */
    Timeout timeout();
}
  • OkHttpCall

發(fā)現(xiàn),OkHttpCall是對(duì)OkHttp的一層封裝,做了一些響應(yīng)碼的處理,和Convert轉(zhuǎn)換器的調(diào)用,OkHttpCall類是沒有數(shù)據(jù)轉(zhuǎn)換的,而Retrofit的Call類則是有Convert的支持,實(shí)現(xiàn)數(shù)據(jù)和模型的轉(zhuǎn)換

/**
 * Call接口的實(shí)現(xiàn),使用OkHttp進(jìn)行請(qǐng)求,并進(jìn)行結(jié)果回調(diào)的封裝類,具有數(shù)據(jù)和模型的轉(zhuǎn)換能力
 */
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);
        }
    }

    /**
     * 獲取真實(shí)請(qǐng)求的實(shí)例,就是OkHttp的Call
     */
    @GuardedBy("this")
    private okhttp3.Call getRawCall() throws IOException {
        okhttp3.Call call = rawCall;
        //已經(jīng)生成過了,直接返回
        if (call != null) {
            return call;
        }

        //不是第一次進(jìn)行接口請(qǐng)求,并且發(fā)生錯(cuò)誤,把錯(cuò)誤再次拋出
        if (creationFailure != null) {
            if (creationFailure instanceof IOException) {
                throw (IOException) creationFailure;
            } else if (creationFailure instanceof RuntimeException) {
                throw (RuntimeException) creationFailure;
            } else {
                throw (Error) creationFailure;
            }
        }

        //創(chuàng)建OkHttp的Call對(duì)象
        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) {
            //調(diào)用了一次enqueue()異步請(qǐng)求,不能再次調(diào)用
            if (executed) throw new IllegalStateException("Already executed.");
            executed = true;

            call = rawCall;
            failure = creationFailure;
            //創(chuàng)建OkHttp的Call對(duì)象
            if (call == null && failure == null) {
                try {
                    call = rawCall = createRawCall();
                } catch (Throwable t) {
                    throwIfFatal(t);
                    failure = creationFailure = t;
                }
            }
        }

        //失敗了,回調(diào)外部
        if (failure != null) {
            callback.onFailure(this, failure);
            return;
        }

        //取消了任務(wù),對(duì)真實(shí)請(qǐng)求做取消
        if (canceled) {
            call.cancel();
        }

        //發(fā)起異步請(qǐng)求
        call.enqueue(new okhttp3.Callback() {
            @Override
            public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
                Response<T> response;
                try {
                    //執(zhí)行,并解析響應(yīng),統(tǒng)一返回Retrofit的Response對(duì)象
                    response = parseResponse(rawResponse);
                } catch (Throwable e) {
                    //解析失敗,回調(diào)外部
                    throwIfFatal(e);
                    callFailure(e);
                    return;
                }
                //解析成功,回調(diào)外部
                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) {
                //請(qǐng)求失敗,回調(diào)外部
                callFailure(e);
            }

            /**
             * 回調(diào)失敗
             */
            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;

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

            call = getRawCall();
        }

        //如果被取消,則取消任務(wù)
        if (canceled) {
            call.cancel();
        }

        //執(zhí)行,并解析響應(yīng),統(tǒng)一返回Retrofit的Response對(duì)象
        return parseResponse(call.execute());
    }

    /**
     * 創(chuàng)建OkHttp3的Call對(duì)象
     */
    private okhttp3.Call createRawCall() throws IOException {
        okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
        //設(shè)置的OkHttpClient,不能返回null
        if (call == null) {
            throw new NullPointerException("Call.Factory returned null.");
        }
        return call;
    }

    /**
     * 執(zhí)行,并解析響應(yīng),統(tǒng)一返回Retrofit的Response對(duì)象
     */
    Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
        ResponseBody rawBody = rawResponse.body();

        //移除真實(shí)請(qǐng)求的Body,方便傳遞
        rawResponse = rawResponse
                .newBuilder()
                .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
                .build();

        int code = rawResponse.code();
        //響應(yīng)碼不為正常的
        if (code < 200 || code >= 300) {
            try {
                ResponseBody bufferedBody = Utils.buffer(rawBody);
                //生成錯(cuò)誤的Response對(duì)象
                return Response.error(bufferedBody, rawResponse);
            } finally {
                //關(guān)閉流
                rawBody.close();
            }
        }

        //204:請(qǐng)求成功了,但是沒有相應(yīng)體
        //205:請(qǐng)求成功了,重置表單,一般WebView才有
        if (code == 204 || code == 205) {
            rawBody.close();
            //由于沒有響應(yīng)體,直接返回成功
            return Response.success(null, rawResponse);
        }

        //包裝一層,捕獲異常
        ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
        try {
            //把ResponseBody轉(zhuǎn)換具體的泛型模型類
            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;
        }
        //取消任務(wù)
        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轉(zhuǎn)換器

Converter轉(zhuǎn)換器主要是做2種事情

  • Json上傳類型的請(qǐng)求時(shí),模型轉(zhuǎn)Json
  • 接口響應(yīng)時(shí),Json轉(zhuǎn)模型

而Gson就擁有這樣的能力,所以Retrofit也提供Gson的轉(zhuǎn)換器工廠,GsonConverterFactory

簡單使用

Retrofit.Builder構(gòu)建時(shí),通過addConverterFactory,添加GsonConverterFactory轉(zhuǎn)換器

//創(chuàng)建Retrofit實(shí)例
Retrofit retrofit = new Retrofit.Builder()
        //配置OkHttpClient
        .callFactory(new OkHttpClient.Builder().build())
        //配置基礎(chǔ)Url
        .baseUrl("https://www.wanandroid.com")
        //Gson轉(zhuǎn)換器
        .addConverterFactory(GsonConverterFactory.create())
        //開始創(chuàng)建
        .build();
  • 添加一個(gè)請(qǐng)求方法,可以直接寫模型的泛型
public interface WanAndroid {
    /**
     * Retrofit Call,獲取首頁文章列表,如果不添加轉(zhuǎn)換器,則泛型只能是ResponseBody
     */
    @GET("article/list/{page}/json")
    Call<ResponseBody> getHomeArticleByCall(@Path("page") int page);

    /**
     * 添加了轉(zhuǎn)換器,則可以直接用模型類的泛型,不需要ResponseBody了
     */
    @GET("article/list/{page}/json")
    Call<HttpModel<PageModel<HomeArticleModel>>> getHomeArticleByCallWithConverter(
            @Path("page") int page
    );
}
  • 調(diào)用,不需要自己做Json和模型的轉(zhuǎn)換,優(yōu)雅了許多
wanAndroid.getHomeArticleByCallWithConverter(page).enqueue(new Callback<HttpModel<PageModel<HomeArticleModel>>>() {
    @Override
    public void onResponse(Call<HttpModel<PageModel<HomeArticleModel>>> call,
                           Response<HttpModel<PageModel<HomeArticleModel>>> response) {
        //請(qǐng)求成功
    }

    @Override
    public void onFailure(Call<HttpModel<PageModel<HomeArticleModel>>> call, Throwable throwable) {
        //請(qǐng)求失敗
    }
});

源碼分析

  • 轉(zhuǎn)換器工廠,實(shí)現(xiàn)Converter.Factory接口
/**
 * Gson轉(zhuǎn)換器工廠
 */
public final class GsonConverterFactory extends Converter.Factory {
    /**
     * 創(chuàng)建方法,使用默認(rèn)構(gòu)造方法的Gson實(shí)例,JSON解碼使用UTF-8
     */
    public static GsonConverterFactory create() {
        return create(new Gson());
    }

    /**
     * 指定Gson實(shí)例進(jìn)行創(chuàng)建
     */
    @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響應(yīng)數(shù)據(jù)轉(zhuǎn)模型
        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請(qǐng)求方式時(shí),模型轉(zhuǎn)Json
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new GsonRequestBodyConverter<>(gson, adapter);
    }
}
  • GsonRequestBodyConverter,Json請(qǐng)求方式時(shí),模型轉(zhuǎn)Json的轉(zhuǎn)換器
/**
 * Json請(qǐng)求方式時(shí),模型轉(zhuǎn)Json的轉(zhuǎn)換器
 */
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響應(yīng)數(shù)據(jù)轉(zhuǎn)模型的轉(zhuǎn)換器
/**
 * ResponseBody響應(yīng)數(shù)據(jù)轉(zhuǎn)模型的轉(zhuǎn)換器
 */
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();
    }
  }
}

總結(jié)

Retrofit中,使用了很多設(shè)計(jì)模式,例如:

  • 創(chuàng)建實(shí)例時(shí)使用Builder構(gòu)建者模式,配置更加靈活
  • 代理模式,主要是JDK動(dòng)態(tài)代理,讓我們可以用接口,實(shí)現(xiàn)聲明式Http請(qǐng)求調(diào)用
  • 責(zé)任鏈模式,配置多個(gè)CallAdapter和Converter,查找到最終匹配當(dāng)前調(diào)用的方法的返回值,和Json和模型之間轉(zhuǎn)換
  • 策略模式,不同平臺(tái)的主線程執(zhí)行器實(shí)現(xiàn),通過Platform類拓展不同平臺(tái)的子類
  • 裝飾器模式,ExecutorCallbackCall,實(shí)現(xiàn)Call接口,對(duì)同樣實(shí)現(xiàn)了Call接口的OkHttpCall進(jìn)行裝飾,實(shí)現(xiàn)enqueue()異步請(qǐng)求的回調(diào)在主線程中回調(diào)

既然Retrofit可以兼容多平臺(tái),而鴻蒙系統(tǒng),也是基于Java,同樣有主線程API,我們是不是可以拓展Retrofit的Platform類,實(shí)現(xiàn)鴻蒙上的子線程請(qǐng)求,主線程回調(diào)呢~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容