美文网首页程序员
Retrofit源码分析

Retrofit源码分析

作者: 凌云飞鱼 | 来源:发表于2018-09-20 16:01 被阅读64次

    前言

            Retrofit是Square公司开源的一个针对OkHttp网络请求接口进行二次封装的框架,其网络请求的实质工作仍是由OkHttp来完成,主要工作是将网络请求通过一系列注解的形式进行拆解,并在最终执行网络请求前,将注解解析生成OkHttp请求所需的Okhttp3.Call。通过分析Retrofit源码,来达到深入理解Retrofit的工作流程与原理,以及学习一些值得借鉴的设计模式和启发一些解决问题的思路。
            对于源码中各种参数类型的相关知识,如有不理解的地方,可以参考贾博岩的两篇文章:我眼中的Java-Type体系。
    https://www.jianshu.com/p/7649f86614d3
    https://www.jianshu.com/p/e8eeff12c306

    基本使用

    第一步:集成

    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
    

    第二步:创建接口

    public interface JianShuApi {
    
        @GET("user/{userName}/info")
        Observable<ResponseBody> getPersonalInfo(@Path("userName") String userName);
    
    }
    

    第三步:配置Retrofit并实例化

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://www.jianshu.com")
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    

    第四步:获取接口对象

    JianShuApi api = retrofit.create(JianShuApi.class);
    

    第五步:执行请求

    Call<ResponseBody> call = api.getPersonalInfo("zhangSanLisi");
    //异步请求
    call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            //成功回调
            }
    
           @Override
           public void onFailure(Call<ResponseBody> call, Throwable t) {
            //失败回调
           }
    });
    
    //同步请求
    try {
          Response<ResponseBody> response = call.execute();
    } catch (IOException e) {
          e.printStackTrace();
    }
    

    源码分析

    下面我们按照使用流程来分析:

    1、自定义接口类

    里面的请求方法,主要通过注解的方式来实现各种参数的灵活配置。如常用的请求方式@POST @GET,添加请求参数的@Query @QueryMap,大文件下载@Streaming,多文件提交@Multipart,请求头内容@Header @Headers...,具体注解使用请参考retrofit2.http里面的内容,每个注解都有相关的注释。

    2、Retrofit.Builder

    通过Retrofit.Builder构造者模式来实例化Retrofit对象,主要可配置的内容如下:

    public static final class Builder {
        // 具体使用平台,Platform.get()方法来获取,这里只分析Android
        private final Platform platform;
        // 指定用来构建Call实例的Call.Factory类
        private @Nullable okhttp3.Call.Factory callFactory;
        // 请求的baseUrl,注释建议我们使用相对路径的方式来配置
        // Base URL: http://example.com/api/
        // Endpoint: foo/bar/
        // Result: http://example.com/api/foo/bar/
        private HttpUrl baseUrl;
        // 用于对象序列化(serialization)和反序列化(deserialization),常用GsonConverterFactory
        private final List<Converter.Factory> converterFactories = new ArrayList<>();
        // 请求返回类型(除了Call之外),若Retrofit结合RxJava一起使用,那么就可以添加RxJava2CallAdapterFactory
        // 来返回Observable类型,无缝对接RxJava
        private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
        // 异步回调执行者
        private @Nullable Executor callbackExecutor;
        // 是否提前校验注解方法
        private boolean validateEagerly;
    
        ......
    
        public Retrofit build() {
            // 必须指定baseUrl,否则异常
            if (baseUrl == null) {
                 throw new IllegalStateException("Base URL required.");
            }
            //默认OkHttpClient来创建请求Call
            okhttp3.Call.Factory callFactory = this.callFactory;
            if (callFactory == null) {
                callFactory = new OkHttpClient();
            }
            // Android平台默认回调在主线程
            Executor callbackExecutor = this.callbackExecutor;
            if (callbackExecutor == null) {
               callbackExecutor = platform.defaultCallbackExecutor();
            }
            // 默认添加一个CallAdapter和Converter
            // Make a defensive copy of the adapters and add the default Call adapter.
            List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories); 
            callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    
            // Make a defensive copy of the converters.
            List<Converter.Factory> converterFactories = new ArrayList<>(1 + this.converterFactories.size());
            // Add the built-in converter factory first. This prevents overriding its behavior but also
            // ensures correct behavior when using converters that consume all types.
            converterFactories.add(new BuiltInConverters());
            converterFactories.addAll(this.converterFactories);
    
            return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
                        unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
        }
    }
    
    3、Retrofit.create()
    public final class Retrofit {
    ......
    public <T> T create(final Class<T> service) {
            // 校验class必须是接口,并且不能继承其他接口
            Utils.validateServiceInterface(service);
            // 是否提前校验方法,提前创建ServiceMethod,如果自定义的接口方法存在不合规范则抛出异常
            if (validateEagerly) {
                    eagerlyValidateMethods(service);
            }
            // 返回一个代理对象,当调用api方法的时候,代理对象执行
            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, 
                                                @Nullable Object[] args) throws Throwable {
                             // If the method is a method from Object then defer to normal invocation.
                             if (method.getDeclaringClass() == Object.class) {
                                return method.invoke(this, args);
                             }
                             if (platform.isDefaultMethod(method)) {
                                 return platform.invokeDefaultMethod(method, service, proxy, args);
                             }
                             // 下面这两行是核心代码,生成ServiceMethod和请求OkHttpCall
                             ServiceMethod<Object, Object> serviceMethod =
                                        (ServiceMethod<Object, Object>) loadServiceMethod(method);
                             OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                             // 执行adapt方法,返回指定的数据类型,具体内容会在后面CallAdapter类中说明
                             return serviceMethod.adapt(okHttpCall);
                         }
                    });
            }
    
    ......
    
    ServiceMethod<?, ?> loadServiceMethod(Method method) {
        ServiceMethod<?, ?> result = serviceMethodCache.get(method);
        if (result != null) return result;
        // 同步锁
        synchronized (serviceMethodCache) {
            //  通过method对象,获取对应缓存的ServiceMethod
            result = serviceMethodCache.get(method);
            if (result == null) {
                // 创建ServiceMethod并存入缓存
                result = new ServiceMethod.Builder<>(this, method).build();
                serviceMethodCache.put(method, result);
            }
        }
        return result;
      }
    ......
    }
    

    到这里我们就拿到了接口代理对象对象,当调用接口具体方法api.getPersonalInfo("zhangSanLisi");的时候就会执行invoke方法,获取创建的ServiceMethod对象,执行serviceMethod.adapt(okHttpCall)方法,这里我们指定了请求适配器为RxJava2CallAdapter,则返回Observable。具体参见下面RxJava2CallAdapter的adapt方法

    4、ServiceMethod

    这是Retrofit框架核心类。ServiceMethod类功能是将自定义的接口方法解析适配成Http调用的Call,也就是生成Http请求。该类也是通过构造者模式实例化:new ServiceMethod.Builder<>(this, method).build()。

    final class ServiceMethod<R, T> {
        ......
        // 这个方法会在创建真正OkHttp请求时调用,即OkHttpCall类中createRawCall()方法
        // 参见下面OkHttpCall分析里enqueue方法
        okhttp3.Call toCall(@Nullable Object... args) throws IOException {
            // 通过构造者模式RequestBuilder来创建请求Request
            // 里面有使用到ServiceMethod生成的ParameterHandler对象,主要是解析不同的请求参数,大家可自行查看源码分析
            RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
                    contentType, hasBody, isFormEncoded, isMultipart);
    
            @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
                    ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
    
            int argumentCount = args != null ? args.length : 0;
            if (argumentCount != handlers.length) {
                throw new IllegalArgumentException("Argument count (" + argumentCount
                        + ") doesn't match expected count (" + handlers.length + ")");
            }
    
            for (int p = 0; p < argumentCount; p++) {
                handlers[p].apply(requestBuilder, args[p]);
            }
            // 最终回通过Retrofit里面指定的callFactory执行,这里不指定时,默认是OkHttpClient,这里不做进一步分析,具体可参考OkHttp源码。
            return callFactory.newCall(requestBuilder.build());
        }
        ......
        static final class Builder<T, R> {
            ......
            Builder(Retrofit retrofit, Method method) {
                this.retrofit = retrofit;
                this.method = method;
                // 获取方法注解, 如@POST、@Headers
                this.methodAnnotations = method.getAnnotations();
                // 获取方法参数类型,如String
                this.parameterTypes = method.getGenericParameterTypes();
                // 获取方法参数注解,如@Query
                this.parameterAnnotationsArray = method.getParameterAnnotations();
            }
    
            public ServiceMethod build () {
                /* 
                * 一系列判断之后调用的是 (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
                * 遍历Retrofit配置时设置的callAdapterFactories,如果设置的是RxJava2CallAdapterFactory最终调用其get方法;
                * 经过一系列的返回类型判断,最终返回CallAdapter,这里也就是RxJava2CallAdapter
                */
                callAdapter = createCallAdapter();
                // 返回类型
                responseType = callAdapter.responseType();
                if (responseType == Response.class || responseType == okhttp3.Response.class) {
                    throw methodError("'" + Utils.getRawType(responseType).getName()
                            + "' is not a valid response body type. Did you mean ResponseBody?");
                }
                /* 
                * 获取转换器,也就是序列化和反序列化方式,retrofit.responseBodyConverter(responseType, annotations);
                * 遍历Retrofit配置时设置的converterFactories,设置的Gson,则会调用GsonConverterFactory的responseBodyConverter方法;
                * 返回GsonResponseBodyConverter类,这里将在后面响应回调分析中使用到。
                */
                responseConverter = createResponseConverter();
                for (Annotation annotation : methodAnnotations) {
                    // 遍历方法注解,这里会解析自定义接口里的方法注解并获取对应的value,为最后创建请求okhttp3.Call准备参数
                    parseMethodAnnotation(annotation);
                }
                // 是否指定了请求方式
                if (httpMethod == null) {
                    throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
                }
                // 校验请求方式与编码方式是否不合理。FormUrlEncoded和Multipart这两种编码方式必须使用在有请求体的请求方式中,如:@POST,@PUT
                if (!hasBody) {
                    if (isMultipart) {
                        throw methodError("Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
                    }
                    if (isFormEncoded) {
                        throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
                                + "request body (e.g., @POST).");
                    }
                }
                // 下面是方法参数注解解析并获取其对应的value,方法参数类型不能是泛型和通配符
                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(p, "Parameter type must not include a type variable or wildcard: %s",
                                parameterType);
                    }
                    Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
                    if (parameterAnnotations == null) {
                        throw parameterError(p, "No Retrofit annotation found.");
                    }
                    // 这里parseParameter方法会调用到Retrofit中requestBodyConverter方法
                    // 即GsonRequestBodyConverter类中的convert方法,进行数据序列化。
                    parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
                }
                // 下面一些是判断方法参数注解与请求方式、编码方式是否匹配或冲突
                if (relativeUrl == null && !gotUrl) {
                    throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
                }
                if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
                    throw methodError("Non-body HTTP method cannot contain @Body.");
                }
                if (isFormEncoded && !gotField) {
                    throw methodError("Form-encoded method must contain at least one @Field.");
                }
                if (isMultipart && !gotPart) {
                    throw methodError("Multipart method must contain at least one @Part.");
                }
                // 最终返回ServiceMethod实例对象
                return new ServiceMethod<>(this);
            }
        }
    ......
    }
    

    GsonRequestBodyConverter

    final class GsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
        private static final MediaType MEDIA_TYPE = MediaType.parse("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());
        }
    }
    
    5、RxJava2CallAdapter

    这里根据设置生成相对应的RxJava的被观察者对象

    final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
    ......
        @Override public Object adapt(Call<R> call) {
            // 这里我们只考虑异步的情况,同步基本一致。生成CallEnqueueObservable对象,call为OkHttpCall
            Observable<Response<R>> responseObservable = isAsync
                            ? new CallEnqueueObservable<>(call)
                            : new CallExecuteObservable<>(call);
    
            Observable<?> observable;
            if (isResult) {
                observable = new ResultObservable<>(responseObservable);
            } else if (isBody) {
                observable = new BodyObservable<>(responseObservable);
            } else {
                observable = responseObservable;
            }
            // 指定运行线程,RxJava2CallAdapterFactory.createWithScheduler(Scheduler)指定创建
            if (scheduler != null) {
                observable = observable.subscribeOn(scheduler);
            }
            if (isFlowable) {
                return observable.toFlowable(BackpressureStrategy.LATEST);
            }
            if (isSingle) {
                return observable.singleOrError();
            }
            if (isMaybe) {
                return observable.singleElement();
            }
            if (isCompletable) {
                return observable.ignoreElements();
            }
            return observable;
        }
    }
    
    6、CallEnqueueObservable

    RxJava的方法调用,当被观察者调用.subscribe()订阅之后,会调用到里面的subscribeActual()方法。

    final class CallEnqueueObservable<T> extends Observable<Response<T>> {
            ......
    
            @Override protected void subscribeActual(Observer<? super Response<T>> observer) {
                // Since Call is a one-shot type, clone it for each new observer.
                Call<T> call = originalCall.clone();
                retrofit2.adapter.rxjava2.CallEnqueueObservable.CallCallback<T> callback = new retrofit2.adapter.rxjava2.CallEnqueueObservable.CallCallback<>(call, observer);
                observer.onSubscribe(callback);
                // 这里是将call加入队列,并传入下面的CallCallback对象,异步请求。前面我们说过这歌call对象是OkHttpCall。
                call.enqueue(callback);
            }
    
            private static final class CallCallback<T> implements Disposable, Callback<T> {
            ......
                //下面是正确和失败回调,即调用onNext和onError方法
                @Override public void onResponse(Call<T> call, Response<T> response) {
                    if (disposed) return;
                    try {
                        observer.onNext(response);
                        if (!disposed) {
                            terminated = true;
                            observer.onComplete();
                        }
                     } catch (Throwable t) {
                      ......          
                     }
                 }
    
                 @Override public void onFailure(Call<T> call, Throwable t) {
                     if (call.isCanceled()) return;
                     try {
                        observer.onError(t);
                     } catch (Throwable inner) {
                      ......      
                     }
                  }
            }
    }
    
    7、OkHttpCall

    上面call.enqueue(callback)实际走的就是OkHttpCall的enqueue方法。

    final class OkHttpCall<T> implements Call<T> {
        ......
        @Override
        public void enqueue(final Callback<T> callback) {
            // 回调非空判断
            checkNotNull(callback, "callback == null");
            okhttp3.Call call;
            Throwable failure;
            // 同步锁,创建真正发起网络请求的okhttp3.Call,会ServiceMethod类里toCall方法
            synchronized (this) {
                //  这里会对请求是否执行过判断,也就是说代理对象方法里生成的OkHttpCall只能执行一次
                if (executed) throw new IllegalStateException("Already executed.");
                executed = true;
                call = rawCall;
                failure = creationFailure;
                if (call == null && failure == null) {
                    try {
                        call = rawCall = createRawCall();
                    } catch (Throwable t) {
                        throwIfFatal(t);
                        failure = creationFailure = t;
                    }
                }
            }
    
            if (failure != null) {
                callback.onFailure(this, failure);
                return;
            }
    
            if (canceled) {
                call.cancel();
            }
            // 这里就转到了OkHttp网络请求框架,加入到请求队列里面。
            // 最后回调回调用CallEnqueueObservable中的CallCallback,即onNext或onError方法
            call.enqueue(new okhttp3.Callback() {
                @Override
                public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
                    Response<T> response;
                    try {
                        // 这里是解析响应数据方法
                        response = parseResponse(rawResponse);
                    } catch (Throwable e) {
                        callFailure(e);
                        return;
                    }
    
                    try {
                        callback.onResponse(retrofit2.OkHttpCall.this, response);
                    } catch (Throwable t) {
                        t.printStackTrace();
                    }
                }
    
                @Override
                public void onFailure(okhttp3.Call call, IOException e) {
                    callFailure(e);
                }
    
                private void callFailure(Throwable e) {
                    try {
                        callback.onFailure(retrofit2.OkHttpCall.this, e);
                    } catch (Throwable t) {
                        t.printStackTrace();
                    }
                }
            });
        }
        ......
        private okhttp3.Call createRawCall() throws IOException {
            // 调用的是ServiceMethod里面的toCall()方法
            okhttp3.Call call = serviceMethod.toCall(args);
            if (call == null) {
                throw new NullPointerException("Call.Factory returned null.");
            }
            return call;
        }
    }
    

    下面我们看下异步请求的回调,这里只分析成功回调,失败回调是一样的。
    在上面enqueue方法回调中有parseResponse(rawResponse)这么一行代码,它做的就是解析响应数据的功能。

    Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
            ResponseBody rawBody = rawResponse.body();
    
            // Remove the body's source (the only stateful object) so we can pass the response along.
            rawResponse = rawResponse.newBuilder()
                    .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
                    .build();
    
            int code = rawResponse.code();
            if (code < 200 || code >= 300) {
                try {
                    // Buffer the entire body to avoid future I/O.
                    ResponseBody bufferedBody = Utils.buffer(rawBody);
                    return Response.error(bufferedBody, rawResponse);
                } finally {
                    rawBody.close();
                }
            }
    
            if (code == 204 || code == 205) {
                rawBody.close();
                return Response.success(null, rawResponse);
            }
    
            ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
            try {
                // 这里是核心代码
                T body = serviceMethod.toResponse(catchingBody);
                return Response.success(body, rawResponse);
            } catch (RuntimeException e) {
                // If the underlying source threw an exception, propagate that rather than indicating it was
                // a runtime exception.
                catchingBody.throwIfCaught();
                throw e;
            }
        }
    

    ServiceMethod类中toResponse方法:

    R toResponse(ResponseBody body) throws IOException {
        return responseConverter.convert(body);
    }
    

    这里直接分析核心代码T body = serviceMethod.toResponse(catchingBody);,通过源码可以看到,最终其调用的是Retrofit配置时设置的converterFactories类的convert方法,返回设定的对象,即反序列化响应数据。

    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();
            }
        }
    }
    
    8、ExecutorCallAdapterFactory

    如果我们没有添加CallAdapterFactory请求适配器,则会使用Android平台默认请求适配器ExecutorCallAdapterFactory,调用enqueue方法时会走ExecutorCallbackCall中的enqueue方法,然后执行OkHttpCall的enqueue方法,代码如下:

    @Override public void enqueue(final Callback<T> callback) {
            checkNotNull(callback, "callback == null");
            // 这里的delegate就是OkHttpCall,最终还是走到OkHttpCall的enqueue方法
            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()) {
                                // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
                                callback.onFailure(ExecutorCallAdapterFactory.ExecutorCallbackCall.this, new IOException("Canceled"));
                            } else {
                                callback.onResponse(ExecutorCallAdapterFactory.ExecutorCallbackCall.this, response);
                            }
                        }
                    });
                }
    
                @Override public void onFailure(Call<T> call, final Throwable t) {
                    callbackExecutor.execute(new Runnable() {
                        @Override public void run() {
                            callback.onFailure(ExecutorCallAdapterFactory.ExecutorCallbackCall.this, t);
                        }
                    });
                }
            });
        }
    
    9、BuiltInConverters

    如果没有添加ConverterFactory,则会使用默认的BuiltInConverters进行requestBody序列化和responseBody反序列化。当然,在BuiltInConverters还存在一个重要的类ToStringConverter,不管有没有额外添加ConverterFactory,其在ServiceMethod进行注解解析时都会使用到,具体参见ServiceMethod类中的ParameterHandler<?> parseParameterAnnotation( int p, Type type, Annotation[] annotations, Annotation annotation)方法。

    final class BuiltInConverters extends Converter.Factory {
        // 响应数据反序列化转换器
        @Override
        public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
                                                                Retrofit retrofit) {
            // 根据要求响应数据类型的不同,返回不同的converter
            if (type == ResponseBody.class) {
                return Utils.isAnnotationPresent(annotations, Streaming.class)
                        ? retrofit2.BuiltInConverters.StreamingResponseBodyConverter.INSTANCE
                        : retrofit2.BuiltInConverters.BufferingResponseBodyConverter.INSTANCE;
            }
            if (type == Void.class) {
                return retrofit2.BuiltInConverters.VoidResponseBodyConverter.INSTANCE;
            }
            return null;
        }
        // 请求体数据序列化转化器
        @Override
        public Converter<?, RequestBody> requestBodyConverter(Type type,Annotation[] parameterAnnotations, 
                                    Annotation[] methodAnnotations, Retrofit retrofit) {
            if (RequestBody.class.isAssignableFrom(Utils.getRawType(type))) {
                return retrofit2.BuiltInConverters.RequestBodyConverter.INSTANCE;
            }
            return null;
        }
    
        static final class VoidResponseBodyConverter implements Converter<ResponseBody, Void> {
            static final retrofit2.BuiltInConverters.VoidResponseBodyConverter 
                            INSTANCE = new retrofit2.BuiltInConverters.VoidResponseBodyConverter();
            @Override public Void convert(ResponseBody value) {
                // 不需要返回,直接close,返回null
                value.close();
                return null;
            }
        }
        // RequestBody请求体转换器
        static final class RequestBodyConverter implements Converter<RequestBody, RequestBody> {
            static final retrofit2.BuiltInConverters.RequestBodyConverter 
                      INSTANCE = new retrofit2.BuiltInConverters.RequestBodyConverter();
            @Override public RequestBody convert(RequestBody value) {
                return value;
            }
        }
        // 流转换器
        static final class StreamingResponseBodyConverter
                implements Converter<ResponseBody, ResponseBody> {
            static final retrofit2.BuiltInConverters.StreamingResponseBodyConverter 
                      INSTANCE = new retrofit2.BuiltInConverters.StreamingResponseBodyConverter();
            @Override public ResponseBody convert(ResponseBody value) {
                return value;
            }
        }
        // 容器转换器
        static final class BufferingResponseBodyConverter
                implements Converter<ResponseBody, ResponseBody> {
            static final retrofit2.BuiltInConverters.BufferingResponseBodyConverter
                        INSTANCE = new retrofit2.BuiltInConverters.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 retrofit2.BuiltInConverters.ToStringConverter 
                         INSTANCE = new retrofit2.BuiltInConverters.ToStringConverter();
            @Override public String convert(Object value) {
                return value.toString();
            }
        }
    }
    

    注意事项

    通过源码的分析,发现一些特别需要注意的事项:
    1、必须指定一个请求方式,并且不能设置两个或两个以上,请求方式有:@POST、@GET、@DELETE、@HEAD、@PATCH、@PUT、@OPTIONS、@HTTP;
    2、Retrofit配置时设置的baseUrl与设置请求方式对应的relativeUrl,结合后要是一个合理的url,不能同时relativeUrl为null,而又不添加@Url;
    3、返回数据类型不能是Retrofit中的Responseokhttp3.Response
    4、请求过程中生成OkHttpCall对象,只能调用一次请求,不能重复调用;
    5、默认响应数据返回ResponseBody, 请求体@Body可使用RequestBody,当使用自定义实体bean时,不管做为@Body值还是作为响应数据类型都必须添加一个ConverterFactory,如常用的GsonConverterFactory
    6、注解的使用不能胡乱搭配,比如:@Multipart和@isFormEncoded与@GET等没有请求体的请求方式一起使用,再者添加了@Multipart,在参数里面必须要有@Part注解。具体的可以分析ServiceMethod类中的parseParameterAnnotation方法。

    总结

            这次分析以Retrofit使用流程为主线,熟悉Retrofit的工作机制以及一些注意事项。Retrofit中使用了几种设计模式:构造者模式(Builder)、工厂模式(Factory)、策略模式(不同的CallAdapter和Converter)、观察者模式等等,这些都是在以后的工作中可以值得借鉴的地方。还有就是注解的使用,这是一个很好的范例,基本上注解使用和解析的相关知识全部都涉及到了,可以阅读一下文章开始推荐的Java-Type体系,是两篇值得一读好文章。
            以上就是本次分析的全部内容,由于个人能力有限,如有不足或错误的地方,敬请谅解。

    相关文章

      网友评论

      本文标题:Retrofit源码分析

      本文链接:https://www.haomeiwen.com/subject/perinftx.html