Android Retrofit 框架的接口代理与调用模块源码深度剖析(二)

一、引言

在 Android 开发中,网络请求是必不可少的一部分。Retrofit 作为一个广泛使用的类型安全的 HTTP 客户端,极大地简化了网络请求的操作。其核心在于接口代理与调用模块,它将接口方法的调用巧妙地转化为实际的 HTTP 请求,并处理响应结果。本文将深入 Retrofit 框架的源码,详细剖析接口代理与调用模块的实现细节。

二、Retrofit 基本使用回顾

在深入源码之前,先简单回顾一下 Retrofit 的基本使用:

java

java 复制代码
// 定义 API 接口
public interface GitHubService {
    // 使用 GET 请求获取用户信息
    @GET("users/{user}")
    Call<ResponseBody> getUser(@Path("user") String user);
}

// 创建 Retrofit 实例
Retrofit retrofit = new Retrofit.Builder()
       .baseUrl("https://api.github.com/")
       .build();

// 创建 API 接口的代理对象
GitHubService service = retrofit.create(GitHubService.class);

// 调用接口方法
Call<ResponseBody> call = service.getUser("octocat");
// 执行异步请求
call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        // 处理响应结果
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        // 处理请求失败
    }
});

从上述代码可以看出,使用 Retrofit 进行网络请求主要分为以下几个步骤:定义 API 接口、创建 Retrofit 实例、创建接口代理对象、调用接口方法和执行请求。下面我们将逐步深入这些步骤背后的源码实现。

三、Retrofit 实例创建

3.1 Retrofit.Builder 类

Retrofit 实例的创建通常使用 Retrofit.Builder 类,该类提供了一系列的配置方法。以下是 Retrofit.Builder 类的部分源码:

java

java 复制代码
public static final class Builder {
    // OkHttp 的请求工厂,用于创建实际的 HTTP 请求
    private okhttp3.Call.Factory callFactory;
    // 基础 URL
    private HttpUrl baseUrl;
    // 调用适配器工厂列表,用于将网络请求结果适配为不同的类型
    private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
    // 转换器工厂列表,用于将请求参数和响应结果进行序列化和反序列化
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    // 回调执行器,用于将回调切换到指定线程
    private Executor callbackExecutor;
    // 是否验证服务接口
    private boolean validateEagerly;

    public Builder() {
        // 默认使用 OkHttpClient 作为请求工厂
        this(Platform.get());
    }

    Builder(Platform platform) {
        // 添加默认的调用适配器工厂
        callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    }

    // 设置请求工厂
    public Builder callFactory(okhttp3.Call.Factory factory) {
        this.callFactory = checkNotNull(factory, "factory == null");
        return this;
    }

    // 设置基础 URL
    public Builder baseUrl(String baseUrl) {
        checkNotNull(baseUrl, "baseUrl == null");
        return baseUrl(HttpUrl.get(baseUrl));
    }

    public Builder baseUrl(HttpUrl baseUrl) {
        checkNotNull(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;
    }

    // 添加调用适配器工厂
    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
        callAdapterFactories.add(checkNotNull(factory, "factory == null"));
        return this;
    }

    // 添加转换器工厂
    public Builder addConverterFactory(Converter.Factory factory) {
        converterFactories.add(checkNotNull(factory, "factory == null"));
        return this;
    }

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

    // 是否验证服务接口
    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;
        if (callFactory == null) {
            // 如果没有设置请求工厂,使用默认的 OkHttpClient
            callFactory = new OkHttpClient();
        }

        Executor callbackExecutor = this.callbackExecutor;
        if (callbackExecutor == null) {
            // 如果没有设置回调执行器,使用平台默认的执行器
            callbackExecutor = Platform.get().defaultCallbackExecutor();
        }

        // 复制调用适配器工厂列表,并添加默认的调用适配器工厂
        List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
        callAdapterFactories.addAll(Platform.get().defaultCallAdapterFactories(callbackExecutor));

        // 复制转换器工厂列表,并添加默认的转换器工厂
        List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
        converterFactories.add(0, new BuiltInConverters());

        return new Retrofit(callFactory, baseUrl, converterFactories, callAdapterFactories,
                callbackExecutor, validateEagerly);
    }
}

Retrofit.Builder 类的主要作用是配置 Retrofit 实例的各种参数,包括请求工厂、基础 URL、调用适配器工厂、转换器工厂和回调执行器等。在 build() 方法中,会对这些参数进行检查和默认值的设置,最终创建一个 Retrofit 实例。

3.2 Retrofit 类

Retrofit 类是 Retrofit 框架的核心类,它封装了各种配置信息,并提供了创建接口代理对象的方法。以下是 Retrofit 类的部分源码:

java

java 复制代码
public final class Retrofit {
    // OkHttp 的请求工厂
    private final okhttp3.Call.Factory callFactory;
    // 基础 URL
    private final HttpUrl baseUrl;
    // 转换器工厂列表
    private final List<Converter.Factory> converterFactories;
    // 调用适配器工厂列表
    private final List<CallAdapter.Factory> callAdapterFactories;
    // 回调执行器
    private final Executor callbackExecutor;
    // 服务方法缓存
    private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
    // 是否验证服务接口
    private final boolean validateEagerly;

    Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
             List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
             Executor callbackExecutor, boolean validateEagerly) {
        this.callFactory = callFactory;
        this.baseUrl = baseUrl;
        this.converterFactories = unmodifiableList(converterFactories);
        this.callAdapterFactories = unmodifiableList(callAdapterFactories);
        this.callbackExecutor = callbackExecutor;
        this.validateEagerly = validateEagerly;

        if (validateEagerly) {
            // 如果需要验证服务接口,遍历所有方法并加载服务方法
            eagerlyValidateMethods();
        }
    }

    // 获取请求工厂
    public okhttp3.Call.Factory callFactory() {
        return callFactory;
    }

    // 获取基础 URL
    public HttpUrl baseUrl() {
        return baseUrl;
    }

    // 获取转换器工厂列表
    public List<Converter.Factory> converterFactories() {
        return converterFactories;
    }

    // 获取调用适配器工厂列表
    public List<CallAdapter.Factory> callAdapterFactories() {
        return callAdapterFactories;
    }

    // 获取回调执行器
    public Executor callbackExecutor() {
        return callbackExecutor;
    }

    // 创建 API 接口的代理对象
    public <T> T create(final Class<T> service) {
        // 验证传入的 service 是否为接口类型
        validateServiceInterface(service);
        // 使用动态代理创建代理对象
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service},
                new InvocationHandler() {
                    private final Platform platform = Platform.get();

                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args)
                            throws Throwable {
                        // 如果调用的是 Object 类的方法,直接调用
                        if (method.getDeclaringClass() == Object.class) {
                            return method.invoke(this, args);
                        }
                        // 如果是默认方法,根据平台进行处理
                        if (platform.isDefaultMethod(method)) {
                            return platform.invokeDefaultMethod(method, service, proxy, args);
                        }
                        // 创建 ServiceMethod 对象
                        ServiceMethod<Object, Object> serviceMethod =
                                (ServiceMethod<Object, Object>) loadServiceMethod(method);
                        // 创建 OkHttpCall 对象
                        OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                        // 通过 CallAdapter 进行适配
                        return serviceMethod.callAdapter.adapt(okHttpCall);
                    }
                });
    }

    // 加载服务方法
    ServiceMethod<?, ?> loadServiceMethod(Method method) {
        // 从缓存中获取 ServiceMethod 对象
        ServiceMethod<?, ?> result = serviceMethodCache.get(method);
        if (result != null) return result;

        synchronized (serviceMethodCache) {
            // 再次从缓存中获取 ServiceMethod 对象
            result = serviceMethodCache.get(method);
            if (result == null) {
                // 如果缓存中没有,则创建一个新的 ServiceMethod 对象
                result = ServiceMethod.parseAnnotations(this, method);
                // 将新创建的 ServiceMethod 对象放入缓存中
                serviceMethodCache.put(method, result);
            }
        }
        return result;
    }

    // 提前验证服务接口的方法
    private void eagerlyValidateMethods() {
        Platform platform = Platform.get();
        for (Method method : getClass().getDeclaredMethods()) {
            if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
                loadServiceMethod(method);
            }
        }
    }
}

Retrofit 类的主要作用是封装配置信息,并提供 create() 方法用于创建 API 接口的代理对象。在 create() 方法中,会使用 Java 的动态代理机制创建一个实现了指定 API 接口的代理对象,并在 InvocationHandlerinvoke() 方法中处理接口方法的调用。

四、接口代理对象的创建

4.1 create() 方法

create() 方法是创建接口代理对象的核心方法,以下是该方法的详细分析:

java

java 复制代码
public <T> T create(final Class<T> service) {
    // 验证传入的 service 是否为接口类型
    validateServiceInterface(service);
    // 使用动态代理创建代理对象
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service},
            new InvocationHandler() {
                private final Platform platform = Platform.get();

                @Override
                public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable {
                    // 如果调用的是 Object 类的方法,直接调用
                    if (method.getDeclaringClass() == Object.class) {
                        return method.invoke(this, args);
                    }
                    // 如果是默认方法,根据平台进行处理
                    if (platform.isDefaultMethod(method)) {
                        return platform.invokeDefaultMethod(method, service, proxy, args);
                    }
                    // 创建 ServiceMethod 对象
                    ServiceMethod<Object, Object> serviceMethod =
                            (ServiceMethod<Object, Object>) loadServiceMethod(method);
                    // 创建 OkHttpCall 对象
                    OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                    // 通过 CallAdapter 进行适配
                    return serviceMethod.callAdapter.adapt(okHttpCall);
                }
            });
}

create() 方法的主要步骤如下:

  1. 验证接口类型 :调用 validateServiceInterface() 方法验证传入的 service 是否为接口类型。

  2. 使用动态代理创建代理对象:使用 Java 的动态代理机制创建一个实现了指定 API 接口的代理对象。

  3. 实现 InvocationHandler 接口 :在 invoke() 方法中处理接口方法的调用。

    • 如果调用的是 Object 类的方法,直接调用该方法。
    • 如果是接口的默认方法,根据平台进行处理。
    • 调用 loadServiceMethod() 方法创建 ServiceMethod 对象。
    • 使用 ServiceMethod 对象和方法参数创建 OkHttpCall 对象。
    • 调用 serviceMethod.callAdapter.adapt() 方法对 OkHttpCall 对象进行适配。

4.2 validateServiceInterface() 方法

validateServiceInterface() 方法用于验证传入的 service 是否为接口类型,并且检查接口方法是否符合 Retrofit 的要求。以下是该方法的源码:

java

java 复制代码
private void validateServiceInterface(Class<?> service) {
    // 检查传入的 service 是否为接口类型
    if (!service.isInterface()) {
        throw new IllegalArgumentException("API declarations must be interfaces.");
    }
    // 检查接口是否有默认方法,并且平台是否支持默认方法
    if (Platform.get().isDefaultMethodProblematic()) {
        for (Method method : service.getDeclaredMethods()) {
            if (Platform.get().isDefaultMethod(method)) {
                throw new IllegalArgumentException(
                        "@SkipCallbackExecutor annotation is required on methods "
                                + "with default implementations when targeting API 24 and lower due "
                                + "to an issue with default method dispatch.");
            }
        }
    }
}

该方法主要检查传入的 service 是否为接口类型,并且在某些平台下检查接口是否有默认方法。

4.3 loadServiceMethod() 方法

loadServiceMethod() 方法用于创建 ServiceMethod 对象,该对象封装了 API 接口方法的元数据。以下是该方法的源码:

java

java 复制代码
ServiceMethod<?, ?> loadServiceMethod(Method method) {
    // 从缓存中获取 ServiceMethod 对象
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
        // 再次从缓存中获取 ServiceMethod 对象
        result = serviceMethodCache.get(method);
        if (result == null) {
            // 如果缓存中没有,则创建一个新的 ServiceMethod 对象
            result = ServiceMethod.parseAnnotations(this, method);
            // 将新创建的 ServiceMethod 对象放入缓存中
            serviceMethodCache.put(method, result);
        }
    }
    return result;
}

loadServiceMethod() 方法首先从缓存中获取 ServiceMethod 对象,如果缓存中没有,则调用 ServiceMethod.parseAnnotations() 方法创建一个新的 ServiceMethod 对象,并将其放入缓存中。

4.4 ServiceMethod.parseAnnotations() 方法

ServiceMethod.parseAnnotations() 方法用于解析 API 接口方法的注解,创建 ServiceMethod 对象。以下是该方法的详细源码和分析:

java

java 复制代码
static <T, R> ServiceMethod<T, R> parseAnnotations(Retrofit retrofit, Method method) {
    // 创建 RequestFactory 对象,用于解析请求相关的注解
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

    // 获取方法的返回类型
    Type returnType = method.getGenericReturnType();
    if (Utils.hasUnresolvableType(returnType)) {
        throw methodError(method,
                "Method return type must not include a type variable or wildcard: %s", returnType);
    }
    if (returnType == void.class) {
        throw methodError(method, "Service methods cannot return void.");
    }

    // 获取 CallAdapter 对象,用于适配网络请求的结果
    CallAdapter<T, R> callAdapter = createCallAdapter(retrofit, method, returnType);
    // 获取响应类型
    Type responseType = callAdapter.responseType();
    if (Utils.hasUnresolvableType(responseType)) {
        throw methodError(method, "Call adapter returned a type that contains wildcards: %s",
                responseType);
    }

    // 获取 Converter 对象,用于将响应结果进行反序列化
    Converter<ResponseBody, T> responseConverter =
            createResponseConverter(retrofit, method, responseType);

    // 获取 OkHttp 的请求工厂
    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    return new ServiceMethod<>(requestFactory, callAdapter, responseConverter, callFactory);
}

// 创建 CallAdapter 对象
private static <T, R> CallAdapter<T, R> createCallAdapter(Retrofit retrofit, Method method, Type returnType) {
    Annotation[] annotations = method.getAnnotations();
    try {
        // 遍历调用适配器工厂列表,查找合适的 CallAdapter 工厂
        for (CallAdapter.Factory factory : retrofit.callAdapterFactories()) {
            CallAdapter<?, ?> adapter = factory.get(returnType, annotations, retrofit);
            if (adapter != null) {
                // 找到合适的 CallAdapter 工厂,返回其创建的 CallAdapter 对象
                return (CallAdapter<T, R>) adapter;
            }
        }
    } catch (RuntimeException e) {
        throw methodError(method, e, "Unable to create call adapter for %s", returnType);
    }
    throw methodError(method, "Could not locate call adapter for %s.", returnType);
}

// 创建响应转换器对象
private static <T> Converter<ResponseBody, T> createResponseConverter(Retrofit retrofit, Method method, Type responseType) {
    Annotation[] annotations = method.getAnnotations();
    try {
        // 遍历转换器工厂列表,查找合适的 Converter 工厂
        for (Converter.Factory factory : retrofit.converterFactories()) {
            Converter<ResponseBody, ?> converter = factory.responseBodyConverter(responseType, annotations, retrofit);
            if (converter != null) {
                // 找到合适的 Converter 工厂,返回其创建的 Converter 对象
                return (Converter<ResponseBody, T>) converter;
            }
        }
    } catch (RuntimeException e) {
        throw methodError(method, e, "Unable to create converter for %s", responseType);
    }
    throw methodError(method, "Could not locate response converter for %s.", responseType);
}

ServiceMethod.parseAnnotations() 方法的主要步骤如下:

  1. 创建 RequestFactory 对象 :调用 RequestFactory.parseAnnotations() 方法解析请求相关的注解,创建 RequestFactory 对象。
  2. 获取方法的返回类型 :通过 method.getGenericReturnType() 方法获取方法的返回类型,并进行合法性检查。
  3. 获取 CallAdapter 对象 :调用 createCallAdapter() 方法,遍历调用适配器工厂列表,查找合适的 CallAdapter 工厂,并返回其创建的 CallAdapter 对象。
  4. 获取响应类型 :通过 callAdapter.responseType() 方法获取响应类型,并进行合法性检查。
  5. 获取 Converter 对象 :调用 createResponseConverter() 方法,遍历转换器工厂列表,查找合适的 Converter 工厂,并返回其创建的 Converter 对象。
  6. 创建 ServiceMethod 对象 :将上述对象作为参数创建 ServiceMethod 对象。

4.5 RequestFactory.parseAnnotations() 方法

RequestFactory.parseAnnotations() 方法用于解析 API 接口方法的请求相关注解,创建 RequestFactory 对象。以下是该方法的详细源码和分析:

java

java 复制代码
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    // 创建 RequestFactory.Builder 对象
    return new Builder(retrofit, method).build();
}

// RequestFactory.Builder 类
static final class Builder {
    private final Retrofit retrofit;
    private final Method method;
    private final Annotation[] methodAnnotations;
    private final Annotation[][] parameterAnnotationsArray;
    private final Type[] parameterTypes;
    private HttpUrl baseUrl;
    private String httpMethod;
    private boolean hasBody;
    private boolean isFormEncoded;
    private boolean isMultipart;
    private String relativeUrl;
    private 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);
        }

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

        // 解析参数注解
        int parameterCount = parameterAnnotationsArray.length;
        parameterHandlers = new ParameterHandler<?>[parameterCount];
        for (int p = 0; p < parameterCount; p++) {
            Type parameterType = parameterTypes[p];
            if (Utils.hasUnresolvableType(parameterType)) {
                throw parameterError(method, p, "Parameter type must not include a type variable or wildcard: %s",
                        parameterType);
            }

            Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
            if (parameterAnnotations == null) {
                throw parameterError(method, p, "No Retrofit annotation found.");
            }

            parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
        }

        if (relativeUrl == null && !hasBody) {
            throw methodError(method, "Non-body HTTP method cannot contain @Body.");
        }

        if (isFormEncoded && isMultipart) {
            throw methodError(method, "Only one encoding annotation is allowed.");
        }

        return new RequestFactory(this);
    }

    private void parseMethodAnnotation(Annotation annotation) {
        if (annotation instanceof GET) {
            parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
        } else if (annotation instanceof POST) {
            parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
        } else if (annotation instanceof PUT) {
            parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
        } else if (annotation instanceof DELETE) {
            parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
        } else if (annotation instanceof HEAD) {
            parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
            if (hasBody) {
                throw methodError(method, "@HEAD method must not have a request body.");
            }
        } else if (annotation instanceof PATCH) {
            parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
        } else if (annotation instanceof OPTIONS) {
            parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
        } else if (annotation instanceof HTTP) {
            HTTP http = (HTTP) annotation;
            parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
        } else if (annotation instanceof retrofit2.http.Headers) {
            String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
            if (headersToParse.length == 0) {
                throw methodError(method, "@Headers annotation is empty.");
            }
            headers = parseHeaders(headersToParse);
        } else if (annotation instanceof Multipart) {
            if (isFormEncoded) {
                throw methodError(method, "Only one encoding annotation is allowed.");
            }
            isMultipart = true;
        } else if (annotation instanceof FormUrlEncoded) {
            if (isMultipart) {
                throw methodError(method, "Only one encoding annotation is allowed.");
            }
            isFormEncoded = true;
        }
    }

    private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
        if (this.httpMethod != null) {
            throw methodError(method, "Only one HTTP method is allowed. Found: %s and %s.",
                    this.httpMethod, httpMethod);
        }
        this.httpMethod = httpMethod;
        this.hasBody = hasBody;

        if (value.isEmpty()) {
            return;
        }

        // Get the relative URL path and existing query string, if present.
        int question = value.indexOf('?');
        if (question != -1 && question < value.length() - 1) {
            // Ensure the query string does not have any named parameters.
            String queryParams = value.substring(question + 1);
            Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
            if (queryParamMatcher.find()) {
                throw methodError(method, "URL query string "%s" must not have replace block. "
                        + "For dynamic query parameters use @Query.", queryParams);
            }
        }

        this.relativeUrl = value;
        this.relativeUrlParamNames = parsePathParameters(value);
    }

    private ParameterHandler<?> parseParameter(
            int p, Type parameterType, Annotation[] annotations) {
        ParameterHandler<?> result = null;
        for (Annotation annotation : annotations) {
            ParameterHandler<?> annotationAction = parseParameterAnnotation(
                    p, parameterType, annotations, annotation);

            if (annotationAction == null) continue;

            if (result != null) {
                throw parameterError(method, p, "Multiple Retrofit annotations found, only one allowed.");
            }

            result = annotationAction;
        }

        if (result == null) {
            throw parameterError(method, p, "No Retrofit annotation found.");
        }

        return result;
    }

    private ParameterHandler<?> parseParameterAnnotation(
            int p, Type type, Annotation[] annotations, Annotation annotation) {
        if (annotation instanceof retrofit2.http.Path) {
            retrofit2.http.Path path = (retrofit

接着上面的继续分析

4.5 RequestFactory.parseAnnotations() 方法

4.5.1 parseParameterAnnotation 方法详细解析

java

java 复制代码
private ParameterHandler<?> parseParameterAnnotation(
        int p, Type type, Annotation[] annotations, Annotation annotation) {
    if (annotation instanceof retrofit2.http.Path) {
        retrofit2.http.Path path = (retrofit2.http.Path) annotation;
        String name = path.value();
        validatePathName(p, name);
        // 创建 Path 类型的 ParameterHandler,用于处理路径参数
        return new ParameterHandler.Path<>(name,
                retrofit.stringConverter(type, annotations));
    } else if (annotation instanceof retrofit2.http.Query) {
        retrofit2.http.Query query = (retrofit2.http.Query) annotation;
        String name = query.value();
        // 创建 Query 类型的 ParameterHandler,用于处理查询参数
        return new ParameterHandler.Query<>(name,
                retrofit.stringConverter(type, annotations), query.encoded());
    } else if (annotation instanceof retrofit2.http.QueryMap) {
        if (!Map.class.isAssignableFrom(Utils.getRawType(type))) {
            throw parameterError(method, p, "@QueryMap parameter type must be Map.");
        }
        Type keyType = Utils.getSupertype(type, Map.class, String.class);
        if (keyType != String.class) {
            throw parameterError(method, p, "@QueryMap keys must be of type String.");
        }
        Type valueType = Utils.getSupertype(type, Map.class, Object.class);
        // 创建 QueryMap 类型的 ParameterHandler,用于处理查询参数映射
        return new ParameterHandler.QueryMap<>(
                retrofit.stringConverter(valueType, annotations),
                ((retrofit2.http.QueryMap) annotation).encoded());
    } else if (annotation instanceof retrofit2.http.Header) {
        retrofit2.http.Header header = (retrofit2.http.Header) annotation;
        String name = header.value();
        // 创建 Header 类型的 ParameterHandler,用于处理请求头参数
        return new ParameterHandler.Header<>(name,
                retrofit.stringConverter(type, annotations));
    } else if (annotation instanceof retrofit2.http.HeaderMap) {
        if (!Map.class.isAssignableFrom(Utils.getRawType(type))) {
            throw parameterError(method, p, "@HeaderMap parameter type must be Map.");
        }
        Type keyType = Utils.getSupertype(type, Map.class, String.class);
        if (keyType != String.class) {
            throw parameterError(method, p, "@HeaderMap keys must be of type String.");
        }
        Type valueType = Utils.getSupertype(type, Map.class, Object.class);
        // 创建 HeaderMap 类型的 ParameterHandler,用于处理请求头参数映射
        return new ParameterHandler.HeaderMap<>(
                retrofit.stringConverter(valueType, annotations));
    } else if (annotation instanceof retrofit2.http.Field) {
        if (!isFormEncoded) {
            throw parameterError(method, p, "@Field parameters can only be used with form encoding.");
        }
        retrofit2.http.Field field = (retrofit2.http.Field) annotation;
        String name = field.value();
        // 创建 Field 类型的 ParameterHandler,用于处理表单字段参数
        return new ParameterHandler.Field<>(name,
                retrofit.stringConverter(type, annotations), field.encoded());
    } else if (annotation instanceof retrofit2.http.FieldMap) {
        if (!isFormEncoded) {
            throw parameterError(method, p, "@FieldMap parameters can only be used with form encoding.");
        }
        if (!Map.class.isAssignableFrom(Utils.getRawType(type))) {
            throw parameterError(method, p, "@FieldMap parameter type must be Map.");
        }
        Type keyType = Utils.getSupertype(type, Map.class, String.class);
        if (keyType != String.class) {
            throw parameterError(method, p, "@FieldMap keys must be of type String.");
        }
        Type valueType = Utils.getSupertype(type, Map.class, Object.class);
        // 创建 FieldMap 类型的 ParameterHandler,用于处理表单字段参数映射
        return new ParameterHandler.FieldMap<>(
                retrofit.stringConverter(valueType, annotations),
                ((retrofit2.http.FieldMap) annotation).encoded());
    } else if (annotation instanceof retrofit2.http.Part) {
        if (!isMultipart) {
            throw parameterError(method, p, "@Part parameters can only be used with multipart encoding.");
        }
        retrofit2.http.Part part = (retrofit2.http.Part) annotation;
        String name = part.value();
        if (name.isEmpty()) {
            return new ParameterHandler.Part<>();
        }
        MediaType mediaType = null;
        if (!"*/*".equals(name)) {
            try {
                mediaType = MediaType.get(name);
            } catch (IllegalArgumentException e) {
                throw parameterError(method, p, "Malformed media type: %s", name);
            }
        }
        // 创建 Part 类型的 ParameterHandler,用于处理多部分请求的部分数据
        return new ParameterHandler.Part<>(name, mediaType,
                retrofit.stringConverter(type, annotations));
    } else if (annotation instanceof retrofit2.http.PartMap) {
        if (!isMultipart) {
            throw parameterError(method, p, "@PartMap parameters can only be used with multipart encoding.");
        }
        if (!Map.class.isAssignableFrom(Utils.getRawType(type))) {
            throw parameterError(method, p, "@PartMap parameter type must be Map.");
        }
        Type keyType = Utils.getSupertype(type, Map.class, String.class);
        if (keyType != String.class) {
            throw parameterError(method, p, "@PartMap keys must be of type String.");
        }
        Type valueType = Utils.getSupertype(type, Map.class, Object.class);
        // 创建 PartMap 类型的 ParameterHandler,用于处理多部分请求的部分数据映射
        return new ParameterHandler.PartMap<>(
                retrofit.stringConverter(valueType, annotations));
    } else if (annotation instanceof retrofit2.http.Body) {
        if (hasBody) {
            // 创建 Body 类型的 ParameterHandler,用于处理请求体
            return new ParameterHandler.Body<>(retrofit.requestBodyConverter(type, annotations, methodAnnotations));
        }
        throw parameterError(method, p, "@Body parameters cannot be used with HTTP methods "
                + "that do not have a request body (e.g., GET, HEAD).");
    } else if (annotation instanceof retrofit2.http.Tag) {
        // 创建 Tag 类型的 ParameterHandler,用于设置请求标签
        return new ParameterHandler.Tag<>(type);
    }

    return null;
}

这个方法会根据不同的注解类型创建不同的 ParameterHandler 对象,这些对象负责处理接口方法参数在请求中的不同使用方式,比如作为路径参数、查询参数、请求头参数等。

4.5.2 build 方法总结

java

java 复制代码
RequestFactory build() {
    // 解析方法注解
    for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
    }

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

    // 解析参数注解
    int parameterCount = parameterAnnotationsArray.length;
    parameterHandlers = new ParameterHandler<?>[parameterCount];
    for (int p = 0; p < parameterCount; p++) {
        Type parameterType = parameterTypes[p];
        if (Utils.hasUnresolvableType(parameterType)) {
            throw parameterError(method, p, "Parameter type must not include a type variable or wildcard: %s",
                    parameterType);
        }

        Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
        if (parameterAnnotations == null) {
            throw parameterError(method, p, "No Retrofit annotation found.");
        }

        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
    }

    if (relativeUrl == null && !hasBody) {
        throw methodError(method, "Non-body HTTP method cannot contain @Body.");
    }

    if (isFormEncoded && isMultipart) {
        throw methodError(method, "Only one encoding annotation is allowed.");
    }

    return new RequestFactory(this);
}

build 方法首先解析方法上的注解,确定 HTTP 请求方法、路径等信息。然后解析每个参数上的注解,创建对应的 ParameterHandler 数组。最后进行一些合法性检查,确保请求配置的正确性,最终创建并返回 RequestFactory 对象。

五、接口方法的调用

5.1 InvocationHandler.invoke() 方法回顾

java

java 复制代码
@Override
public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
    // 如果调用的是 Object 类的方法,直接调用
    if (method.getDeclaringClass() == Object.class) {
        return method.invoke(this, args);
    }
    // 如果是默认方法,根据平台进行处理
    if (platform.isDefaultMethod(method)) {
        return platform.invokeDefaultMethod(method, service, proxy, args);
    }
    // 创建 ServiceMethod 对象
    ServiceMethod<Object, Object> serviceMethod =
            (ServiceMethod<Object, Object>) loadServiceMethod(method);
    // 创建 OkHttpCall 对象
    OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
    // 通过 CallAdapter 进行适配
    return serviceMethod.callAdapter.adapt(okHttpCall);
}

当调用接口方法时,会触发 InvocationHandlerinvoke 方法。该方法首先判断调用的是否为 Object 类的方法或者接口的默认方法,若是则直接处理。否则,会加载 ServiceMethod 对象,创建 OkHttpCall 对象,最后通过 CallAdapter 进行适配。

5.2 OkHttpCall

5.2.1 类的基本结构和成员变量

java

java 复制代码
final class OkHttpCall<T> implements Call<T> {
    private final ServiceMethod<T, ?> serviceMethod;
    private final Object[] args;
    private volatile boolean canceled;

    private @Nullable okhttp3.Call rawCall;
    private @Nullable Throwable creationFailure;
    private boolean executed;

    OkHttpCall(ServiceMethod<T, ?> serviceMethod, Object[] args) {
        this.serviceMethod = serviceMethod;
        this.args = args;
    }
    // ...其他方法
}

OkHttpCall 类实现了 Call 接口,封装了 ServiceMethod 和方法参数。rawCall 是 OkHttp 的 Call 对象,用于实际执行 HTTP 请求。executed 标志该请求是否已经执行过,canceled 标志请求是否被取消。

5.2.2 request 方法

java

java 复制代码
@Override
public synchronized Request request() {
    okhttp3.Call call = rawCall;
    if (call != null) {
        return call.request();
    }
    if (creationFailure != null) {
        if (creationFailure instanceof IOException) {
            throw new RuntimeException("Unable to create request.", creationFailure);
        } else {
            throw (RuntimeException) creationFailure;
        }
    }

    try {
        // 创建 OkHttp 的 Request 对象
        rawCall = call = serviceMethod.toCall(args);
        return call.request();
    } catch (RuntimeException | Error e) {
        creationFailure = e;
        throw e;
    }
}

request 方法用于获取实际的 OkHttp 请求对象。如果 rawCall 已经创建,则直接返回其请求对象。如果创建请求时出现异常,会抛出相应的异常。否则,调用 serviceMethod.toCall(args) 方法创建 rawCall 并返回其请求对象。

5.2.3 enqueue 方法

java

java 复制代码
@Override
public void enqueue(final Callback<T> callback) {
    checkNotNull(callback, "callback == null");

    okhttp3.Call call;
    Throwable failure;

    synchronized (this) {
        if (executed) throw new IllegalStateException("Already executed.");
        executed = true;

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

    if (failure != null) {
        // 处理创建请求时的异常
        callback.onFailure(this, failure);
        return;
    }

    if (canceled) {
        call.cancel();
    }

    // 执行请求并处理响应
    call.enqueue(new okhttp3.Callback() {
        @Override
        public void onFailure(okhttp3.Call call, IOException e) {
            // 切换到主线程回调失败结果
            callbackOnMain(e);
        }

        @Override
        public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
            Response<T> response;
            try {
                // 解析响应结果
                response = parseResponse(rawResponse);
            } catch (Throwable e) {
                // 处理解析响应时的异常
                callbackOnMain(e);
                return;
            }

            // 切换到主线程回调成功结果
            callbackOnMain(response);
        }
    });
}

// 切换到主线程回调的辅助方法
private void callbackOnMain(final Throwable t) {
    // 获取主线程的执行器
    executorService.execute(new Runnable() {
        @Override
        public void run() {
            callback.onFailure(OkHttpCall.this, t);
        }
    });
}

private void callbackOnMain(final Response<T> response) {
    executorService.execute(new Runnable() {
        @Override
        public void run() {
            if (response.isSuccessful()) {
                callback.onResponse(OkHttpCall.this, response);
            } else {
                callback.onFailure(OkHttpCall.this, new IOException("HTTP " + response.code()));
            }
        }
    });
}

enqueue 方法用于异步执行请求。首先进行同步控制,确保请求只执行一次。然后创建 rawCall 对象,如果创建过程中出现异常,直接回调失败结果。接着判断请求是否被取消,若取消则取消 rawCall。最后使用 rawCallenqueue 方法异步执行请求,并在回调中处理响应结果。callbackOnMain 方法用于将回调切换到主线程。

5.2.4 parseResponse 方法

java

java 复制代码
private Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    // 解析响应头
    Headers headers = Headers.of(rawResponse.headers());

    if (!rawResponse.isSuccessful()) {
        // 处理非成功响应
        rawBody.close();
        return Response.error(parseErrorBodyIfPossible(rawResponse), headers);
    }

    if (rawBody == null) {
        // 处理空响应体
        return Response.success(null, headers);
    }

    // 解析响应体
    T body = serviceMethod.toResponse(rawBody);
    return Response.success(body, headers);
}

// 解析错误响应体
private IOException parseErrorBodyIfPossible(okhttp3.Response rawResponse) {
    try {
        return serviceMethod.parseError(rawResponse);
    } catch (RuntimeException e) {
        return e;
    } catch (IOException e) {
        return e;
    } catch (Throwable t) {
        return new RuntimeException(t);
    }
}

parseResponse 方法用于解析 OkHttp 的响应结果。如果响应状态码不是 2xx,会处理错误响应。如果响应体为空,返回成功但 bodynull 的响应。否则,调用 serviceMethod.toResponse(rawBody) 方法解析响应体并返回成功响应。

5.3 ServiceMethod.toCall 方法

java

java 复制代码
okhttp3.Call toCall(Object... args) {
    // 创建 OkHttp 的 Request 对象
    Request request = requestFactory.create(args);
    // 使用 OkHttp 的 Call.Factory 创建 Call 对象
    return callFactory.newCall(request);
}

toCall 方法调用 requestFactory.create(args) 方法创建 OkHttp 的 Request 对象,然后使用 callFactory 创建 Call 对象,用于实际执行 HTTP 请求。

5.4 RequestFactory.create 方法

java

java 复制代码
Request create(Object... args) {
    // 解析请求 URL
    HttpUrl baseUrl = this.baseUrl;
    String relativeUrl = this.relativeUrl;
    HttpUrl.Builder urlBuilder = baseUrl.newBuilder(relativeUrl);
    if (urlBuilder == null) {
        throw new IllegalArgumentException("Malformed URL.");
    }

    // 解析请求参数
    ParameterHandler<?>[] parameterHandlers = this.parameterHandlers;
    Headers.Builder headersBuilder = new Headers.Builder();
    RequestBody body = null;
    for (int i = 0; i < parameterHandlers.length; i++) {
        parameterHandlers[i].apply(args[i], urlBuilder, headersBuilder, bodyBuilder);
    }

    // 创建 OkHttp 的 Request 对象
    return new Request.Builder()
           .url(urlBuilder.build())
           .headers(headersBuilder.build())
           .method(httpMethod, bodyBuilder.build())
           .build();
}

create 方法根据 baseUrlrelativeUrl 构建请求 URL。然后遍历 parameterHandlers 数组,将方法参数应用到请求的 URL、请求头和请求体中。最后使用 Request.Builder 创建 OkHttp 的 Request 对象。

六、CallAdapter 的适配过程

6.1 CallAdapter 接口和工厂类

java

java 复制代码
public interface CallAdapter<R, T> {
    // 获取响应类型
    Type responseType();

    // 适配 Call 对象
    T adapt(Call<R> call);

    // 工厂类,用于创建 CallAdapter 对象
    abstract class Factory {
        // 根据返回类型和注解创建 CallAdapter 对象
        public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
                                                        Retrofit retrofit);

        // 辅助方法,用于获取类型中的原始类型
        protected static Type getParameterUpperBound(int index, ParameterizedType type) {
            return Utils.getParameterUpperBound(index, type);
        }

        // 辅助方法,用于获取类型中的原始类型
        protected static Class<?> getRawType(Type type) {
            return Utils.getRawType(type);
        }
    }
}

CallAdapter 接口定义了两个方法,responseType 用于获取响应类型,adapt 用于适配 Call 对象。Factory 是一个抽象类,用于创建 CallAdapter 对象。

6.2 ExecutorCallAdapterFactoryExecutorCallAdapter

java

java 复制代码
public final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
    final Executor callbackExecutor;

    public ExecutorCallAdapterFactory(Executor callbackExecutor) {
        this.callbackExecutor = callbackExecutor;
    }

    @Override
    public @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
                                           Retrofit retrofit) {
        if (getRawType(returnType) != Call.class) {
            return null;
        }
        final Type responseType = Utils.getCallResponseType(returnType);
        return new ExecutorCallAdapter<>(callbackExecutor, responseType);
    }
}

final class ExecutorCallAdapter<T, R> implements CallAdapter<T, R> {
    private final Executor callbackExecutor;
    private final Type responseType;

    ExecutorCallAdapter(Executor callbackExecutor, Type responseType) {
        this.callbackExecutor = callbackExecutor;
        this.responseType = responseType;
    }

    @Override
    public Type responseType() {
        return responseType;
    }

    @Override
    public R adapt(Call<T> call) {
        // 创建适配后的 Call 对象
        return (R) new ExecutorCallbackCall<>(callbackExecutor, call);
    }
}

final class ExecutorCallbackCall<T> implements Call<T> {
    private final Executor callbackExecutor;
    private final Call<T> delegate;

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

    @Override
    public void enqueue(final Callback<T> callback) {
        // 检查回调是否为 null
        checkNotNull(callback, "callback == null");

        // 执行原始请求,并在回调时切换线程
        delegate.enqueue(new Callback<T>() {
            @Override
            public void onResponse(Call<T> call, final Response<T> response) {
                // 切换到指定线程回调
                callbackExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        if (delegate.isCanceled()) {
                            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(new Runnable() {
                    @Override
                    public void run() {
                        callback.onFailure(ExecutorCallbackCall.this, t);
                    }
                });
            }
        });
    }

    // 其他方法直接委托给原始 Call 对象
    @Override
    public Response<T> execute() throws IOException {
        return delegate.execute();
    }

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

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

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

    @Override
    public Call<T> clone() {
        return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
    }

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

ExecutorCallAdapterFactory 是默认的 CallAdapter 工厂类,它会根据返回类型判断是否为 Call 类型,如果是则创建 ExecutorCallAdapter 对象。ExecutorCallAdapteradapt 方法会创建 ExecutorCallbackCall 对象,该对象会将回调切换到指定的线程。

七、Converter 的转换过程

7.1 Converter 接口和工厂类

java

java 复制代码
public interface Converter<F, T> {
    // 转换方法
    T convert(F value) throws IOException;

    // 工厂类,用于创建 Converter 对象
    abstract class Factory {
        // 创建请求体转换器
        public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
                                                                        Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
            return null;
        }

        // 创建响应体转换器
        public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
                                                                           Annotation[] annotations, Retrofit retrofit) {
            return null;
        }

        // 创建字符串转换器
        public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
                                                              Retrofit retrofit) {
            return null;
        }
    }
}

Converter 接口定义了 convert 方法,用于进行数据转换。Factory 是一个抽象类,提供了创建请求体转换器、响应体转换器和字符串转换器的方法。

7.2 GsonConverterFactory 和相关转换器

java

java 复制代码
public final class GsonConverterFactory extends Converter.Factory {
    private final Gson gson;

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

    public static GsonConverterFactory create() {
        return create(new Gson());
    }

    public static GsonConverterFactory create(Gson gson) {
        return new GsonConverterFactory(gson);
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        return new GsonResponseBodyConverter<>(gson, type);
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        return new GsonRequestBodyConverter<>(gson, type);
    }
}

final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
    private final Gson gson;
    private final TypeAdapter<T> adapter;

    GsonResponseBodyConverter(Gson gson, Type type) {
        this.gson = gson;
        this.adapter = gson.getAdapter(TypeToken.get(type));
    }

    @Override
    public T convert(ResponseBody value) throws IOException {
        JsonReader jsonReader = gson.newJsonReader(value.charStream());
        try {
            return adapter.read(jsonReader);
        } finally {
            value.close();
        }
    }
}

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, Type type) {
        this.gson = gson;
        this.adapter = gson.getAdapter(TypeToken.get(type));
    }

    @Override
    public RequestBody convert(T value) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        JsonWriter jsonWriter = gson.newJsonWriter(new OutputStreamWriter(out, UTF_8));
        adapter.write(jsonWriter, value);
        jsonWriter.close();
        return RequestBody.create(MEDIA_TYPE, out.toByteArray());
    }
}

GsonConverterFactory 是一个使用 Gson 进行序列化和反序列化的 Converter 工厂类。它会创建 GsonResponseBodyConverterGsonRequestBodyConverter,分别用于将响应体和请求参数转换为指定类型。

八、总结

通过对 Retrofit 接口代理与调用模块的源码分析,我们可以看到 Retrofit 是一个设计精巧、模块化程度高的框架。其核心流程如下:

8.1 核心流程概述

  • Retrofit 实例创建 :利用 Retrofit.Builder 类对 Retrofit 实例的各项配置进行设置,像请求工厂、基础 URL、调用适配器工厂、转换器工厂以及回调执行器等。最终调用 build() 方法生成 Retrofit 实例。
  • 接口代理对象创建 :借助 Retrofit 实例的 create() 方法,运用 Java 动态代理机制创建 API 接口的代理对象。在 InvocationHandlerinvoke() 方法里处理接口方法的调用,涵盖加载 ServiceMethod 对象、创建 OkHttpCall 对象以及通过 CallAdapter 进行适配等操作。
  • 方法注解解析ServiceMethod.parseAnnotations() 方法对 API 接口方法的注解加以解析,创建 RequestFactoryCallAdapterConverter 对象,并最终构建 ServiceMethod 对象。RequestFactory 负责解析请求相关注解,明确 HTTP 请求方法、路径以及参数处理方式。
  • 请求执行OkHttpCall 类封装了 ServiceMethod 和方法参数,其 enqueue() 方法用于异步执行请求。在该方法中,会创建 OkHttp 的 Call 对象,若创建过程出现异常则回调失败结果,接着判断请求是否取消,若未取消则使用 Call 对象的 enqueue() 方法异步执行请求,并处理响应结果。
  • 结果适配与转换CallAdapter 负责将网络请求结果适配为不同类型,例如 CallObservable 等。Converter 负责对请求参数和响应结果进行序列化和反序列化,Retrofit 提供了多种默认的 Converter,像 GsonConverterFactoryMoshiConverterFactory 等。

8.2 设计优点

  • 高度模块化 :Retrofit 将不同功能拆分成多个模块,如 CallAdapterConverter 等,每个模块职责明确。开发者能够根据自身需求替换或扩展这些模块,例如使用不同的 CallAdapter 来适配 RxJava、Kotlin Coroutines 等异步编程库,或者使用不同的 Converter 来处理不同格式的数据。
  • 注解驱动:通过注解来定义 API 接口方法的请求信息,如 HTTP 请求方法、路径、参数等,使代码简洁且易于理解和维护。同时,注解的使用也提高了代码的可读性和可维护性,开发者可以清晰地看到每个方法的请求信息。
  • 与 OkHttp 集成:Retrofit 底层使用 OkHttp 作为 HTTP 客户端,借助 OkHttp 的强大功能,如连接池管理、拦截器、缓存等,提高了网络请求的性能和稳定性。

8.3 性能优化点

  • 缓存机制 :可利用 OkHttp 的缓存功能,减少不必要的网络请求。通过设置合适的缓存策略,如根据响应头的 Cache-Control 字段进行缓存,能够提高应用的响应速度和节省用户流量。
  • 拦截器使用:使用 OkHttp 的拦截器对请求和响应进行拦截处理,例如添加请求头、记录日志、重试请求等。合理使用拦截器可以提高代码的复用性和可维护性。
  • 异步处理 :Retrofit 支持异步请求,使用 enqueue() 方法进行异步调用,避免在主线程中进行网络请求,防止阻塞主线程,提高应用的响应性能。

8.4 可扩展性分析

  • 自定义 CallAdapter :开发者可以自定义 CallAdapter 来适配不同的异步编程库,如 RxJava、Kotlin Coroutines 等。通过实现 CallAdapter.Factory 接口和 CallAdapter 接口,开发者可以将网络请求结果转换为自定义的类型,实现更灵活的异步处理。
  • 自定义 Converter :可以自定义 Converter 来处理不同格式的数据,如 XML、Protocol Buffers 等。通过实现 Converter.Factory 接口和 Converter 接口,开发者可以将请求参数和响应结果转换为自定义的格式,满足不同的业务需求。

8.5 潜在问题与解决方案

  • 注解使用不当:若注解使用错误,可能会导致请求配置错误。开发者需要仔细阅读 Retrofit 的文档,正确使用各种注解,同时在开发过程中进行充分的测试,确保请求配置的正确性。
  • 内存泄漏风险 :在使用异步请求时,如果没有正确处理回调,可能会导致内存泄漏。开发者需要在适当的时候取消请求,避免在 Activity 或 Fragment 销毁时仍然持有引用。可以在 onDestroy() 方法中调用 call.cancel() 方法取消请求。
  • 异常处理复杂 :网络请求过程中可能会出现各种异常,如网络连接失败、服务器错误等。开发者需要在代码中进行全面的异常处理,确保应用在出现异常时能够给出友好的提示信息。可以在 CallbackonFailure() 方法中对不同的异常进行处理,根据异常类型给出不同的提示信息。

九、拓展与未来发展趋势

9.1 与新兴技术的融合

  • Kotlin 协程 :随着 Kotlin 在 Android 开发中的广泛应用,Retrofit 可以更好地与 Kotlin 协程集成。通过自定义 CallAdapter,可以将网络请求封装为协程的挂起函数,使异步编程更加简洁和直观。例如,可以创建一个 CoroutineCallAdapterFactory,将 Call 对象转换为 Deferred 或直接在协程中使用的挂起函数。
  • Flow :Kotlin 的 Flow 是一种异步数据流,它可以用于处理多个连续的异步事件。Retrofit 可以与 Flow 集成,将网络请求的响应转换为 Flow 流,方便开发者进行数据的流式处理和组合。例如,可以通过自定义 CallAdapterCall 对象转换为 Flow 对象,实现数据的实时更新和处理。

9.2 性能优化的进一步探索

  • HTTP/3 支持:HTTP/3 是 HTTP 协议的下一代版本,它基于 QUIC 协议,具有更快的连接速度和更好的性能。Retrofit 可以考虑支持 HTTP/3,以进一步提高网络请求的性能。这需要对 OkHttp 进行升级,使其支持 HTTP/3 协议,并在 Retrofit 中进行相应的配置和适配。
  • 智能缓存策略:结合机器学习和数据分析技术,实现智能缓存策略。根据用户的使用习惯、网络环境等因素,动态调整缓存的有效期和缓存策略,提高缓存的命中率和性能。例如,可以分析用户的请求频率和请求内容,预测用户可能的请求,提前进行缓存。

9.3 安全与隐私保护

  • 数据加密:在网络请求过程中,对敏感数据进行加密处理,确保数据的安全性。可以在请求体和响应体中添加加密算法,对数据进行加密和解密操作。例如,使用 AES 加密算法对请求参数和响应结果进行加密,防止数据在传输过程中被窃取。
  • 隐私保护:遵守相关的隐私法规,如 GDPR 等,对用户的个人信息进行保护。在网络请求中,避免传输不必要的个人信息,对必须传输的个人信息进行脱敏处理。例如,对用户的手机号码、身份证号码等敏感信息进行脱敏处理,只传输部分信息。

9.4 跨平台支持

  • Flutter:随着 Flutter 在跨平台开发中的流行,Retrofit 可以考虑提供对 Flutter 的支持。可以开发一个 Flutter 版本的 Retrofit 库,让 Flutter 开发者也能够享受到 Retrofit 的便捷性和高性能。这需要将 Retrofit 的核心功能进行重构,使其能够在 Flutter 环境中运行。

  • React Native:同样,Retrofit 也可以考虑支持 React Native 平台。通过开发一个 React Native 版本的 Retrofit 库,为 React Native 开发者提供一个强大的网络请求解决方案。这需要与 React Native 的生态系统进行集成,实现与 JavaScript 代码的交互。

综上所述,Retrofit 作为一个优秀的网络请求框架,在 Android 开发中发挥着重要作用。通过深入分析其源码,我们不仅可以了解其内部实现原理,还可以发现其潜在的优化点和拓展方向。随着技术的不断发展,Retrofit 有望在性能、功能和跨平台支持等方面取得更大的进步。

相关推荐
鸿蒙布道师1 小时前
鸿蒙NEXT开发动画案例2
android·ios·华为·harmonyos·鸿蒙系统·arkui·huawei
androidwork2 小时前
Kotlin Android工程Mock数据方法总结
android·开发语言·kotlin
xiangxiongfly9154 小时前
Android setContentView()源码分析
android·setcontentview
人间有清欢5 小时前
Android开发补充内容
android·okhttp·rxjava·retrofit·hilt·jetpack compose
人间有清欢6 小时前
Android开发报错解决
android
每次的天空7 小时前
Android学习总结之kotlin协程面试篇
android·学习·kotlin
每次的天空9 小时前
Android学习总结之Binder篇
android·学习·binder
峥嵘life9 小时前
Android 有线网开发调试总结
android
是店小二呀10 小时前
【算法-链表】链表操作技巧:常见算法
android·c++·算法·链表
zhifanxu12 小时前
Kotlin 遍历
android·开发语言·kotlin