Retrofit源码分析

在上一篇中介绍来Retrofit如何使用,如果有不清楚Retrofit的使用的话可以看我的上一篇文章Retrofit快速入门使用
那么这一篇我们就从源码的角度来深入的了解Retrofit的实现,本篇文章基于Retrofit2.4.0来分析。

一般我们会使用如下方式来创建一个retrofit对象,

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://www.sojson.com")
            .addConverterFactory(GsonConverterFactory.create())
            .build();
weatherInterface = retrofit.create(WeatherInterface.class);
Call<Weather> callSZ = weatherInterface.getWeather("深圳");
callSZ.enqueue(new Callback<Weather>() {
    @Override
    public void onResponse(Call<Weather> call, Response<Weather> response) {
        weatherInfo.setText(response.body().toString());
    }

    @Override
    public void onFailure(Call<Weather> call, Throwable t) {
        weatherInfo.setText("请求失败");
    }
});

那么,就这么几步到底做了那些事情呢,下面我们来一步一步的分析它们。

step1:创建builder

Retrofit使用来构建者模式来创建Retrofit对象,和OkHttp的风格一样。

public Builder() {
    //获取一个平台对象
    this(Platform.get());
}

在Builder的构造方法中获取了一个和平台相关的Platform对象,Retrofit目前支持Android平台和java平台,不过在之前版本的代码中还会支持IOS平台。进入Platform中查看它的源码,因为代码不多,这里就全部贴出来了。

class Platform {
    //Platform在被加载后就会获取当前的平台对象
    private static final Platform PLATFORM = findPlatform();
    static Platform get() {
        return PLATFORM;
    }
    //findPlatform()是根据不同平台中的类来确定当前的运行环境是什么平台
    private static Platform findPlatform() {
        try {
            //这个类非常熟悉,是Android中的类
            //如果这个类存在并且Android版本大于0就返回一个Android平台对象
            Class.forName("android.os.Build");
            if (Build.VERSION.SDK_INT != 0) {
                return new Android();
            }
        } catch (ClassNotFoundException ignored) {
        }
        try {
            //如果不是Android平台再查找是否存在
            Optional这个类
            //该类定义在java.util.这个包下,如果存在说明是Java平台
            Class.forName("java.util.Optional");
            return new Java8();
        } catch (ClassNotFoundException ignored) {
        }
        //返回默认的平台
        return new Platform();
    }

    /**
    * Platform会返回一个用于切换线程的executor对象,这里的Executor只是一个接口而已
    * 该Executor用来切换请求结果callback的执行线程,默认返回空
    */
    @Nullable
    Executor defaultCallbackExecutor() {
        return null;
    }

    CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
        if (callbackExecutor != null) {
            return new ExecutorCallAdapterFactory(callbackExecutor);
        }
        return DefaultCallAdapterFactory.INSTANCE;
    }

    boolean isDefaultMethod(Method method) {
        return false;
    }

    //java8中有一个新的特性就是接口的默认实现,使用default关键字标识
    @Nullable
    Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
                               @Nullable Object... args) throws Throwable {
        throw new UnsupportedOperationException();
    }

    static class Java8 extends Platform {
        //判断该方法是不是默认的接口实现方法
        @Override
        boolean isDefaultMethod(Method method) {
            return method.isDefault();
        }
        @Override
        Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
                                   @Nullable Object... args) throws Throwable {
            Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
            constructor.setAccessible(true);
            return constructor.newInstance(declaringClass, -1
                    .unreflectSpecial(method, declaringClass)
                    .bindTo(object)
                    .invokeWithArguments(args);
        }
    }

    //Android平台
    static class Android extends Platform {
        //返回将callback切换到主线程执行的Executor
        @Override
        public Executor defaultCallbackExecutor() {
            return new MainThreadExecutor();
        }
        //Android平台下默认的CallAdapterFactory为ExecutorCallAdapterFactor
        @Override
        CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
            if (callbackExecutor == null) throw new AssertionError();
            return new ExecutorCallAdapterFactory(callbackExecutor);
        }

        static class MainThreadExecutor implements Executor {
            private final Handler handler = new Handler(Looper.getMainLooper());
            //这里使用了handler将runnable任务切换到主线程中执行
            @Override
            public void execute(Runnable r) {
                handler.post(r);
            }
        }
    }
}

step2:通过builder设置参数

Retrofit的Builder提供了几个方法来设置Retrofit的核心参数:

//这几个参数和Retorift中对应
private final Platform platform;
private @Nullable okhttp3.Call.Factory callFactory;
private HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;
/**
 * OkHttpClient本身实现了okhttp3.Call.Factory这个接口,
 *一般我们直接使用OkHttp的时候都是直接调用OkHttpClient的newCall()方法来创建一个Call请求
 * 这里又会调用callFactory()方法来设置callFactory对象
 */
public Builder client(OkHttpClient client)

/**
* 设置callFactory对象,用来创建call请求
*/
public Builder callFactory(okhttp3.Call.Factory factory)
/**
* 设置请求URL的基础url,该基础url包含{协议://主机:端口号/},这里的基础url末尾需要以/结尾
* 最终该基础url和接口中的url会拼接为一个完整的url,所以retrofit是一个RESTful的网络请求框架
*/
public Builder baseUrl(String baseUrl)
/**
* 添加一个Converter工厂对象,Converter类可以对请求结果按照用户的要求做进一步的转换
*/
public Builder addConverterFactory(Converter.Factory factory)

/**
* 添加一个请求适配器,该适配器会将默认的OkHttpCall转换为其他框架需要的对象,比如转换为一个Observable对象
*/
public Builder addCallAdapterFactory(CallAdapter.Factory factory)
/**
* 设置callback线程切换的executor
*/
public Builder callbackExecutor(Executor executor)
//该标记标识是否提前通过反射构建出接口中定义的方法,默认不提前
public Builder validateEagerly(boolean validateEagerly)

通过以上方法设置好这些参数后通过build()方法创建出了Retrofit对象。

step3:创建Retrofit对象

public Retrofit build() {
    //baseurl如果为null抛出异常,所以这个参数一定要设置
    if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
    }

    okhttp3.Call.Factory callFactory = this.callFactory;
    //如果callactory为null则默认使用OkHttpClient
    if (callFactory == null) {
        callFactory = new OkHttpClient();
    }

    Executor callbackExecutor = this.callbackExecutor;
    if (callbackExecutor == null) {
        //在Android平台下这里返回的就是MainThreadExecutor
        callbackExecutor = platform.defaultCallbackExecutor();
    }

    //在自定义的CallAdapter.Factory后面会再添加一个默认的CallAdapter.Factory
    List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
    //在Android平台下,该默认的CallAdapter.Factory为ExecutorCallAdapterFactory
    callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

    List<Converter.Factory> converterFactories =
            new ArrayList<>(1 + this.converterFactories.size());
    // 在自定义Converter.Factory之前会添加一个内置的BinltInConverters对象
    converterFactories.add(new BuiltInConverters());
    converterFactories.addAll(this.converterFactories);
    //创建返回Retrofit对象
    return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
            unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}

再有了Retrofit对象后,我们调用了create()方法来创建接口对象。

step4:创建请求接口对象

在使用Retrofit的时候,我们只是定义了一个接口而已,并没有它的实现,一开始我还以为是Retrofit在编译期间来动态生成对应的实现类,通过查看源码发现并不是这样的,而是通过动态代理的方式来创建出这个接口对象,如果不清楚动态代理的观众请自行补习相关内容,这里就不说什么是动态代理了,具体我们查看源码:

public <T> T create(final Class<T> service) {
    //判断该service是否是一个符合要求的接口class
    //Retrofit要求定义的接口不能继承别的接口
    Utils.validateServiceInterface(service);
    //如果需要提前构建出接口中的方法,那么这里就会调用loadServiceMethod()方法通过反射的方式
    //找到接口中所有定义的方法将其封装为一个ServiceMethod对象并缓存
    if (validateEagerly) {
        //提前加载ServiceMethod
        eagerlyValidateMethods(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, @Nullable Object[] args)
                        throws Throwable {
                    //每当我们调用了接口中的方法,都会走到这个invoke()方法中来
                    // 如果执行的方法是在Object类中定义的
                    if (method.getDeclaringClass() == Object.class) {
                        return method.invoke(this, args);
                    }
                    //Android平台下默认为false
                    //在Java平台下,java8新增了一个特性,接口方法的默认实现,在方法声明上加上default即可
                    //在定义接口的时候,可以有方法的实现,然后加上default声明就可以了。
                    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对call请求做一个转换
                    return serviceMethod.adapt(okHttpCall);
                }
            });
}

5、调用接口方法获取请求

通过调用loadServiceMethod()方法,会解析在接口中声明的方法中的注解,将其封装为一个ServiceMethod对象。

ServiceMethod<?, ?> loadServiceMethod(Method method) {
    //先从缓存中获取
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;
    //缓存中没有则创建一个ServiceMethod,然后将其放入缓存中
    synchronized (serviceMethodCache) {
        result = serviceMethodCache.get(method);
        if (result == null) {
            result = new ServiceMethod.Builder<>(this, method).build();
            serviceMethodCache.put(method, result);
        }
    }
    return result;
}

ServieMethod对象也是使用构建者模式来创建的,在ServiceMethod中Builder的构造方法中初始化了如下几个关键参数:

final Retrofit retrofit;
final Method method;
final Annotation[] methodAnnotations;
final Annotation[][] parameterAnnotationsArray;
final Type[] parameterTypes;
Builder(Retrofit retrofit, Method method) {
    this.retrofit = retrofit;
    this.method = method;
    //获取方法上的所有注解
    this.methodAnnotations = method.getAnnotations();
    //获方法参数的类型
    this.parameterTypes = method.getGenericParameterTypes();
    //获取参数上的所有注解
    this.parameterAnnotationsArray = method.getParameterAnnotations();
}

最后调用build()方法创建出了ServiceMethod对象,那么肯定在build()方法中做了解析注解等操作,继续跟踪源码查看:

public ServiceMethod build() {
    //从Retrofit对象中获取callAdapter对象
    callAdapter = createCallAdapter();
    //获取call请求对象的返回值类型
    responseType = callAdapter.responseType();
    //如果返回值类型是Response则抛出异常
    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对象中获取Converter对象,用于将设置的请求体参数转换为一个RequestBody和解析response返回结果
    responseConverter = createResponseConverter();
    //解析方法上的注解
    for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
    }
    //如果没有在方法上设置请求方法,则抛出类型,比如GET、POST这种注解
    if (httpMethod == null) {
        throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
    }
    //如果请求中不能有请求体,比如GET请求方式
    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).");
        }
    }
    //参数上的注解
    int parameterCount = parameterAnnotationsArray.length;
    //创建ParameterHandler数组,parameterhandler用于处理参数上的注解
    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.");
        }
        //解析参数上的注解
        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
    }
    //以下就是判断一些冲突情况了。
    //如果url为空则抛出异常
    if (relativeUrl == null && !gotUrl) {
        throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
    }
    //如果不能有请求体却使用了Body注解抛出异常
    if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
        throw methodError("Non-body HTTP method cannot contain @Body.");
    }
    //如果是表单上传却没有Field注解则抛出异常
    if (isFormEncoded && !gotField) {
        throw methodError("Form-encoded method must contain at least one @Field.");
    }
    //如果是文件上传却没有使用Part注解,则抛出异常
    if (isMultipart && !gotPart) {
        throw methodError("Multipart method must contain at least one @Part.");
    }
    //创建ServiceMethod对象并返回
    return new ServiceMethod<>(this);
}

具体是如何解析注解的这里就不看了,都是一些繁琐的事情。

在获取到了ServiceMethod对象后,接着就创建了OkHttpCall对象,OKHttpCall实现了Call接口,这个Call接口不是OkHttp中的Call接口,而是Retrofit内部自己的接口,不过它和OkHttp中的Call的行为是一样的。这里创建的OkHttpCall也只是保存了ServiceMethod对象和该方法的请求参数。

final class OkHttpCall<T> implements Call<T>

在最后则调用了serviceMethod.adapt(okHttpCall)对call对象进行了适配转换。这里的转换非常重要,如果我们在初始化Retrofit的时候设置了RxJava的callAdapter,那么这里通过适配器转换后则返回的是一个Observable对象。先来瞅一眼RxJavaCallAdapter的adapt方法:

public Object adapt(Call<R> call) {
    ...
    Observable<?> observable = Observable.create(func);
    ...
    return observable;
}

在构造Retrofit对象的时候,如果不设置CallAdapter对象,那么这个callada对象在Android平台下则默认是通过ExecutorCallAdapterFactory来创建的。

final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
    final Executor callbackExecutor;
    //在创建ExecutorCallAdapterFactory对象的时候传递了callbackExecutor对象
    ExecutorCallAdapterFactory(Executor callbackExecutor) {
        this.callbackExecutor = callbackExecutor;
    }

    @Override
    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        //如果返回值不是Call类型,则退出,所以如果我们不是使用RxJava的话,
        //我们在定义接口的时候返回值都是Call类型,如果不是call类型的话就返回空,
        //在Retrofit中会继续调用其他的CallAdapter.Factory对象来处理
        if (getRawType(returnType) != Call.class) {
            return null;
        }
        //请求返回类型,即在接口方法中返回值Call<T>中的这个T类型
        final Type responseType = Utils.getCallResponseType(returnType);
        //返回一个匿名类
        return new CallAdapter<Object, Call<?>>() {
            @Override public Type responseType() {
                return responseType;
            }

            @Override public Call<Object> adapt(Call<Object> call) {
                //这里返回了一个ExecutorCallbackCall对象
                return new ExecutorCallbackCall<>(callbackExecutor, call);
            }
        };
    }

    //ExecutorCallbackCall实际上是一个包装类,使用了装饰器设计模式
    //这里使用装饰器模式的目的是为了异步执行的时候将callback使用executor切换线程来执行
    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) {
            checkNotNull(callback, "callback == null");
            delegate.enqueue(new Callback<T>() {
                @Override public void onResponse(Call<T> call, final Response<T> response) {
                    //这里看到了callbackExecutor的使用,通过callbackExecutor来切换线程调用callback
                    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 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();
        }
    }
}

到这里我们已经清楚了Call请求是如何来的了,而且在ExecutorCallAdapterFactory中会将OkHttpCall转换为一个ExecutorCallbackCall对象,ExecutorCallbackCall是一个包装类,它的功能只是在异步执行请求的时候返回结果时将callback切换到主线程中来执行。那么在调用call的execute或者enqueue方法时会做什么呢,这里的Call并不是OkHttp里面的那个Call,而Retrofit在网路请求的时候还是使用的OkHttp,那么必然有一个地方会将Retrofit创建出来的call请求转换为OkHttp的call。这里就直接贴出OkHttpCall的源码进行分析

final class OkHttpCall<T> implements Call<T> {
    //请求的接口方法
    private final ServiceMethod<T, ?> serviceMethod;
    //请求接口方法中的参数
    private final @Nullable Object[] args;
    //取消标记
    private volatile boolean canceled;
    //真正OkHttp中的call请求
    private @Nullable okhttp3.Call rawCall;

    private @Nullable Throwable creationFailure;
    //是否已经执行的标记
    private boolean executed;

    OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
        this.serviceMethod = serviceMethod;
        this.args = args;
    }

    @Override public OkHttpCall<T> clone() {
        return new OkHttpCall<>(serviceMethod, args);
    }

    //获取OkHttp中的Request请求
    @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 if (creationFailure instanceof RuntimeException) {
                throw (RuntimeException) creationFailure;
            } else {
                throw (Error) creationFailure;
            }
        }
        try {
            return (rawCall = createRawCall()).request();
        } catch (RuntimeException | Error e) {
            throwIfFatal(e); // Do not assign a fatal error to creationFailure.
            creationFailure = e;
            throw e;
        } catch (IOException e) {
            creationFailure = e;
            throw new RuntimeException("Unable to create request.", e);
        }
    }

    //异步执行请求
    @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
                    call = rawCall = createRawCall();
                } catch (Throwable t) {
                    throwIfFatal(t);
                    failure = creationFailure = t;
                }
            }
        }

        if (failure != null) {
            callback.onFailure(this, failure);
            return;
        }

        //这时的call已经是OkHttp中的call请求了
        if (canceled) {
            取消请求
            call.cancel();
        }
        //这里就是okhttp中的异步请求执行了
        call.enqueue(new okhttp3.Callback() {
            @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
                Response<T> response;
                try {
                    //解析response
                    response = parseResponse(rawResponse);
                } catch (Throwable e) {
                    callFailure(e);
                    return;
                }

                try {
                    callback.onResponse(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(OkHttpCall.this, e);
                } catch (Throwable t) {
                    t.printStackTrace();
                }
            }
        });
    }

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

    //同步执行
    @Override public Response<T> execute() throws IOException {
        okhttp3.Call call;

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

            if (creationFailure != null) {
                if (creationFailure instanceof IOException) {
                    throw (IOException) creationFailure;
                } else if (creationFailure instanceof RuntimeException) {
                    throw (RuntimeException) creationFailure;
                } else {
                    throw (Error) creationFailure;
                }
            }

            call = rawCall;
            if (call == null) {
                try {
                    //转换call请求
                    call = rawCall = createRawCall();
                } catch (IOException | RuntimeException | Error e) {
                    throwIfFatal(e); //  Do not assign a fatal error to creationFailure.
                    creationFailure = e;
                    throw e;
                }
            }
        }

        if (canceled) {
            call.cancel();
        }
        //同步执行并解析response
        return parseResponse(call.execute());
    }

    //转换为OkHttp里面的call 请求,生成来处理转换的还是在ServiceMethod中
    private okhttp3.Call createRawCall() throws IOException {
        okhttp3.Call call = serviceMethod.toCall(args);
        if (call == null) {
            throw new NullPointerException("Call.Factory returned null.");
        }
        return call;
    }

    Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
        ResponseBody rawBody = rawResponse.body();
        rawResponse = rawResponse.newBuilder()
                .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
                .build();

        int code = rawResponse.code();
        if (code < 200 || code >= 300) {
            try {
                //如果响应码不在200-300之间
                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) {
            catchingBody.throwIfCaught();
            throw e;
        }
    }

    public void cancel() {
        canceled = true;

        okhttp3.Call call;
        synchronized (this) {
            call = rawCall;
        }
        if (call != null) {
            call.cancel();
        }
    }

    @Override public boolean isCanceled() {
        if (canceled) {
            return true;
        }
        synchronized (this) {
            return rawCall != null && rawCall.isCanceled();
        }
    }
    //不能读取响应体的ResponseBody
    static final class NoContentResponseBody extends ResponseBody {
        private final MediaType contentType;
        private final long contentLength;

        NoContentResponseBody(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 ExceptionCatchingRequestBody extends ResponseBody {
        private final ResponseBody delegate;
        IOException thrownException;

        ExceptionCatchingRequestBody(ResponseBody delegate) {
            this.delegate = delegate;
        }

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

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

        @Override public BufferedSource source() {
            return 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 void close() {
            delegate.close();
        }

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

透过源码可以看到OkHttpCall的工作非常简单,它在这里起到一个承上启下的作用,它还是调用的是OkHttp中的call来执行任务的,而转换为一个OkHttp框架中的Call对象,然后对响应结果进行解析处理,这两个地方真正实现的地方还是在ServiceMethod当中。

//将OkHttpCall转换为一个真正的OkHttp框架中的call,实际上就是通过callFactory来创建了一个call对象
//各位客官如何对OkHttp比较熟悉的话应该对这几行代码非常熟悉,就是我们在使用OkHttp的时候的几个主要步骤
okhttp3.Call toCall(@Nullable Object... args) throws IOException {
    //通过RequestBuilder来构建一个Request请求
    RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
            contentType, hasBody, isFormEncoded, isMultipart);
    //参数的个数要和ParameterHandler数组个数一致
    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]);
    }
    //通过newCall来创建一个Call请求
    //在最开始的时候我们看到callFactory默认情况下就是OkHttp
    return callFactory.newCall(requestBuilder.build());
}

//解析响应结果,使用的是Converter这个对象
R toResponse(ResponseBody body) throws IOException {
    return responseConverter.convert(body);
}

这里的RequestBuilder也起到了承上启下的作用,它里面包含了在接口方法注解上设置的参数,在它的build()中会通过OkHttp的RequestBuilder来构建出OkHttp中的reqeust对象,然后通过newCall方法,将request请求作为参数就创建出了OkHttp中的call对象。RequestBuilder里面都死构建request请求的过程,就不查看它的源码了,它的实现也是非常简单的。

在ServiceMethod中有一个toResponse()方法,它可以将响应的结果解析为我们需要的数据格式,比如我们在创建Retrofit对象的时候设置了GsonConverterFactory,那么这里就会使用gson来解析数据生成我们设置好的数据类型。

通过以上分析我们就清楚了Retrofit的整体执行流程了,有了请求对象后,不管是同步还是异步执行都会走到OkHttp里面去了,到此对Retrofit的分析就结束了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值