Retrofit源码解析

square公司开源了一系列的优秀库,比如Retrofit,OkHttp,Picasso等,

前面简单分析了Picasso的源码,这里来分析下Retrofit的使用:

一、gradle添加依赖

compile ‘com.squareup.okhttp:okhttp:2.4.0‘
compile ‘com.squareup.okhttp:okhttp-urlconnection:2.4.0‘
compile ‘com.squareup.okio:okio:1.5.0‘
compile ‘com.google.code.gson:gson:2.2.4‘

compile ‘com.squareup.retrofit:retrofit:2.0.0-beta2‘
compile ‘com.squareup.retrofit:adapter-rxjava:2.0.0-beta2‘
compile ‘com.squareup.retrofit:converter-gson:2.0.0-beta2‘

compile ‘io.reactivex:rxandroid:1.1.0‘
compile ‘io.reactivex:rxjava:1.1.0‘

盗两张网上的图:

下面是从创建Retrofit出发,具体的使用流程;Retrofit最终的请求操作都是交由okHttp去执行的,执行的结果返回Response,再根据转换器进行解析成相对应的返回类型T;

Retrofit中使用了动态代理,方便了使用;通过retrofit.create返回的其实是个动态代理类,所有具体的处理逻辑交由MethodHandler进行处理;

下面是Retrofit系统中的整个类图,有点像外观模式,Retrofit持有所有子系统的引用;Retrofit比较重要的是两个Factory,一个使用来生成CallAdapter的CallAdapterFactory;一个是用来转换结果的ConvertFactory;这两个都可以用户自己进行添加。

在自定义的Service中,每一个method对应一个MethodHandler,MethodHandler持有retrofit,前面两个Factory以及生成Request的RequestFactory;在okHttp中,Request需要自己进行定义创建,而Retrofit简化了这个操作,进行了相应的封装,使用注解的方式来定义Request的相关参数信息;注解信息的解析则在RequestFactory中完成,通过RequestFactoryParser对注解信息进行简单解析,RequestBuilderAction是解析method中参数中的注解如@Path这些产生的中间产物,最终通过RequestBuilder来具体产生一个Request,RequestBuilder中持有okHttp中的Request.Builder类的引用,其创建Request过程其实都是交给okHttp来操作的;

生成的Request最终封装成为一个OkHttpCall,OkHttpCall则可以看做是对okHttp中Call的通过,它的enqueue等网络请求操作都是委托个给okHttp来操作的;同时对okHttp的返回Response进行解析,使用convertFactory,将其解析为用户所期望的返回类型;

二、使用

(一)使用Call形式

1、定义请求接口:

public interface RetrofirHttpService {
    @GET("{user}")
    Call<UserInfo> getData(@Path("user") String user);
}
注:UserInfo是自己定义的解析类:
public class UserInfo {
    String username;
    String password;
}

2、使用GET获取信息:

// 原始的CallBack方式
private void getUseCall() {
    // 添加拦截器
    OkHttpClient client = new OkHttpClient();
    client.interceptors().add(new LoggingInterceptor());

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://115.156.187.146/TransferServer/")
            .client(client)                                     // 添加okHttp
            .addConverterFactory(GsonConverterFactory.create()) // GSON进行转换
            .build();
    RetrofirHttpService apiStores = retrofit.create(RetrofirHttpService.class);
    Call<UserInfo> call = apiStores.getData("ServerMain.php");

    // 异步调用
    call.enqueue(new Callback<UserInfo>() {
        @Override
        public void onResponse(Response<UserInfo> response, Retrofit retrofit) {
            UserInfo data = response.body();
            LogUtils.i("Call Result:" + data.m);
        }

        @Override
        public void onFailure(Throwable t) {
            LogUtils.e(t.toString());
        }
    });
}

(二)使用RxJava形式

1、定义请求接口

public interface RxHttpService {
    @GET("{path}")
    Observable<UserInfo> getData(@Path("path") String path);
}

2、具体使用

// 使用RxJava方式
private void getUseRxJava() {
    // 添加拦截器
    OkHttpClient client = new OkHttpClient();
    client.interceptors().add(new LoggingInterceptor());

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://115.156.187.146/TransferServer/")
            .client(client)  // 添加okHttp
            .addConverterFactory(GsonConverterFactory.create()) // GSON进行转换
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();

    RxHttpService apiStores = retrofit.create(RxHttpService.class);
    Observable<UserInfo> observable = apiStores.getData("ServerMain.php");
    observable.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<UserInfo>() {
                @Override
                public void onNext(UserInfo user) {
                    LogUtils.i("Call Result:" + user.m);
                }

                @Override
                public void onCompleted() {
                }

                @Override
                public void onError(Throwable error) {
                    LogUtils.e(error.toString());
                }
            });
}

三、源码分析:

(一)先来看创建动态代理类的过程:

RxHttpService apiStores = retrofit.create(RxHttpService.class);

动态代理的知识具体见《 设计模式汇总:结构型模型(上)》中的代理模式中的解释。

1)Retrofit#create:

/** Create an implementation of the API defined by the {@code service} interface. */
@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
        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, 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);
                    }
                    return loadMethodHandler(method).invoke(args);
                }
            });
}

标准的动态代理创建过程;

来看代理类和委托类之间的中间InvocationHandler类的invoke函数具体执行逻辑;

loadMethodHandler(method).invoke(args);

2)Retrofit#loadMethodHandler:

private final Map<Method, MethodHandler<?>> methodHandlerCache = new LinkedHashMap<>();

MethodHandler<?> loadMethodHandler(Method method) {
    MethodHandler<?> handler;
    synchronized (methodHandlerCache) {
        handler = methodHandlerCache.get(method);
        if (handler == null) {
            handler = MethodHandler.create(this, method);
            methodHandlerCache.put(method, handler);
        }
    }
    return handler;
}

Retrofit维护了一个method对应的Map,这里将method都封装成一个MethodHandler类(可以当作是委托类);调用代理类,其实就是调用MethodHandler的invoke;所以具体的实现逻辑都在MethodHandler中;

(二)MethodHanlder

1)MethodHandler类:

final class MethodHandler<T> {
    // MethodHandler持有一个retrofit对象
    private final Retrofit retrofit;
    // 类似于Volley中的 Request ,包含了HTTP请求的Url、Header信息,MediaType、Method以及RequestAction数组
    private final RequestFactory requestFactory;
    // HTTP请求返回数据的类型
    private final CallAdapter<T> callAdapter;
    // 对返回数据进行转换的类型转换器
    private final Converter<ResponseBody, T> responseConverter;

    private MethodHandler(Retrofit retrofit, RequestFactory requestFactory,
                          CallAdapter<T> callAdapter, Converter<ResponseBody, T> responseConverter) {
        this.retrofit = retrofit;
        this.requestFactory = requestFactory;
        this.callAdapter = callAdapter;
        this.responseConverter = responseConverter;
    }

    // 每一次请求的最终具体调用的函数
    Object invoke(Object... args) {
        // 可以发现最终是调用callAdapter的adapt函数
        // 并且将相应的请求事务封装成一个OkHttpCall类进行处理
        return callAdapter.adapt(new OkHttpCall<>(retrofit, requestFactory, responseConverter, args));
    }

    // 调用该静态类创建一个MethodHandler实例
    @SuppressWarnings("unchecked")
    static MethodHandler<?> create(Retrofit retrofit, Method method) {
        // 创建CallAdapter
        CallAdapter<Object> callAdapter = (CallAdapter<Object>) createCallAdapter(method, retrofit);
        // 根据callAdapter来获取相应的返回类型
        Type responseType = callAdapter.responseType();
        // 创建结果类型转换器
        Converter<ResponseBody, Object> responseConverter =
                (Converter<ResponseBody, Object>) createResponseConverter(method, retrofit, responseType);
        // 创建RequestFactory
        RequestFactory requestFactory = RequestFactoryParser.parse(method, responseType, retrofit);
        return new MethodHandler<>(retrofit, requestFactory, callAdapter, responseConverter);
    }

    // 创建相应的CallAdapter
    private static CallAdapter<?> createCallAdapter(Method method, Retrofit retrofit) {
        // 这个method即为service中自定义的一个方法,一般返回都是泛型类
        Type returnType = method.getGenericReturnType();
        if (Utils.hasUnresolvableType(returnType)) {
            throw Utils.methodError(method,
                    "Method return type must not include a type variable or wildcard: %s", returnType);
        }
        if (returnType == void.class) {
            throw Utils.methodError(method, "Service methods cannot return void.");
        }
        // 获取Method上对应的注解即(GET这些)
        Annotation[] annotations = method.getAnnotations();
        try {
            // 根据注解来获取相应的Adapter
            return retrofit.callAdapter(returnType, annotations);
        } catch (RuntimeException e) { // Wide exception range because factories are user code.
            throw Utils.methodError(e, method, "Unable to create call adapter for %s", returnType);
        }
    }

    // 最后也是调用retrofit来实现的;
    private static Converter<ResponseBody, ?> createResponseConverter(Method method,
                                                                      Retrofit retrofit, Type responseType) {
        Annotation[] annotations = method.getAnnotations();
        try {
            return retrofit.responseConverter(responseType, annotations);
        } catch (RuntimeException e) { // Wide exception range because factories are user code.
            throw Utils.methodError(e, method, "Unable to create converter for %s", responseType);
        }
    }
}

MethodHandler是系统为定义的每一个Service中的method中创建的一个具体执行类,通过调用其invoke函数,来执行具体的请求的逻辑;

它主要包含四个变量:

Retrofit: MethodHandler持有一个retrofit对象

private final Retrofit retrofit;

RequestFactory: 类似于Volley中的 Request ,包含了HTTP请求的Url、Header信息,MediaType、Method以及RequestAction数组

private final RequestFactory requestFactory;

CallAdapter: HTTP请求返回数据的类型

private final CallAdapter<T> callAdapter;

ResponseConverter: 对返回数据进行转换的类型转换器

private final Converter<ResponseBody, T> responseConverter;

具体来看每个变量的创建;

2)Retrofit#callAdapter:

private final List<CallAdapter.Factory> adapterFactories;

public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
}
/**
 * Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain
 * #callAdapterFactories() factories} except {@code skipPast}.
 */
// 返回相关的可用的CallAdapter(除了指定跳过的skipPast)
public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
                                      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");

    int start = adapterFactories.indexOf(skipPast) + 1;
    // 遍历adapterFactories中所有的Factory
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
        CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
        // 如果找到,则返回该Adapter
        if (adapter != null) {
            return adapter;
        }
    }

    // 如果获取不到相应的CallAdapter,则抛出异常
    StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
            .append(returnType)
            .append(". Tried:");
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
        builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
    }
    if (skipPast != null) {
        builder.append("\nSkipped:");
        for (int i = 0; i < start; i++) {
            builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
        }
    }
    throw new IllegalArgumentException(builder.toString());
}

RetroFit中有一个adapterFactories保存了所有CallAdapter.Factory,通过遍历这些factory来获取相应符合的CallAdapter;

先来看adapterFactories都保存了哪些Factory;从Retrofit创建开始

(三)Retrofit的创建

private final OkHttpClient client;
private final BaseUrl baseUrl;
private final List<Converter.Factory> converterFactories;
private final List<CallAdapter.Factory> adapterFactories;
private final Executor callbackExecutor;
private final boolean validateEagerly;

private Retrofit(OkHttpClient client, BaseUrl baseUrl, List<Converter.Factory> converterFactories,
                 List<CallAdapter.Factory> adapterFactories, Executor callbackExecutor,
                 boolean validateEagerly) {
    this.client = client;
    this.baseUrl = baseUrl;
    this.converterFactories = converterFactories;
    this.adapterFactories = adapterFactories;
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
}

/** Create the {@link Retrofit} instances. */
public Retrofit build() {
    if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
    }

    // 默认使用OkhttpClient
    OkHttpClient client = this.client;
    if (client == null) {
        client = new OkHttpClient();
    }

    // 向adapterFactories添加了一个默认的CallAdapterFactory
    // 如果前面add了CallAdpterfactory(如RxJavaCallAdapterFactory),则可以看到默认的Factory会添加到用户指定的Factory后面
    // 则在遍历的时候,会优先遍历用户指定的Factory
    List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
    adapterFactories.add(Platform.get().defaultCallAdapterFactory(callbackExecutor));

    // Make a defensive copy of the converters.
    List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

    return new Retrofit(client, baseUrl, converterFactories, adapterFactories, callbackExecutor,
            validateEagerly);
}

/**
 * 用户添加自定义的CallAdapterFactory
 */
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
    adapterFactories.add(checkNotNull(factory, "factory == null"));
    return this;
}

用户可以根据自己需要来添加自定义的CallAdapterFactory,这里来看系统默认的CallAdapterFactory;

Platform.get()是根据系统不同来创建不同的运行环境,比如是再Android上还是Java上运行时由区别的,如下所示:

1)Platform:

class Platform {
    private static final Platform PLATFORM = findPlatform();

    static Platform get() {
        return PLATFORM;
    }

    private static Platform findPlatform() {
        // 如果是Android系统
        try {
            Class.forName("android.os.Build");
            if (Build.VERSION.SDK_INT != 0) {
                return new Android();
            }
        } catch (ClassNotFoundException ignored) {
        }
        // 如果是Java系统
        try {
            Class.forName("java.util.Optional");
            return new Java8();
        } catch (ClassNotFoundException ignored) {
        }
        // 如果是其他系统
        return new Platform();
    }

    static class Android extends Platform {
        // 创建默认的CallAdapterFactory过程
        @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
            if (callbackExecutor == null) {
                // 如果没有指定callbackExecutor,或者为null,则新创建一个MainThreadExecutor
                callbackExecutor = new MainThreadExecutor();
            }
            return new ExecutorCallAdapterFactory(callbackExecutor);
        }

        // 该Executor的主要工作逻辑就是调用主线程的Looper来创建一个对应的Handler
        // 执行execute就是操作Handler进行post事件(Runnable)
        static class MainThreadExecutor implements Executor {
            private final Handler handler = new Handler(Looper.getMainLooper());

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

可以看到对应不同的系统平台,Retrofit提供了不同的Platform版本; 默认的CallAdapterFactory是个ExecutorCallAdapterFactory,它是通过callbackExecutor来创建的;

如果用户没有执行相应的callbackExecutor,系统或创建一个默认的MainThreadExecutor,该MainThreadExecutor的主要执行逻辑就是使用主线程的Handler来post Runnable消息;

然后Retrofit把ExecutorCallAdapterFactory实例添加到adapterFactories中;

2)继续前面MethodHandler的查找CallAdapter的逻辑:

CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
final class ExecutorCallAdapterFactory implements CallAdapter.Factory {
    private final Executor callbackExecutor;

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

    @Override
    public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        // 根据returnType获得具体的返回类型
        if (Utils.getRawType(returnType) != Call.class) {
            return null;
        }
        final Type responseType = Utils.getCallResponseType(returnType);
        // 返回一个CallAdapter
        return new CallAdapter<Call<?>>() {
            @Override
            public Type responseType() {
                return responseType;
            }

            // 调用adapt返回一个ExecutorCallbackCall类
            @Override
            public <R> Call<R> adapt(Call<R> call) {
                return new ExecutorCallbackCall<>(callbackExecutor, call);
            }
        };
    }

将前面所有的逻辑串在一起,使用动态代理创建的代理类使用的InvokeHandler,调用其invoke来实现一个具体的方法调用;委托类是系统自定义创建的MethodHandler,系统根据method来创建相应的MethodHandler;MethodHandler中持有对CallAdapter的引用,CallAdapter是通过相应的CallAdpterFactory来创建的,如果加入了自定义的比如RxJava,最终会添加到Retrofit中的一个factory链表中,系统通过扫描链表来获取合适的CallAdpterFactory来创建CallAdapter;

如果没有自定义CallAdapterFactory,则会默认生成一个CallAdapterFactory;通过这个默认的Factory会创建一个默认的CallAdapter;

代理类的方法实现,是通过InvokeHandler的invoke来实现的;在系统定义的Invokehandler中进而调用MethodHandler的invoke函数,该invoke函数会继续调用CallAdpter的adapt,由上知,最终返回一个ExecutorCallbackCall类;

继续来看ExecutorCallbackCall类:

3)ExecutorCallbackCall类:

final class ExecutorCallAdapterFactory implements CallAdapter.Factory {
    static final class ExecutorCallbackCall<T> implements Call<T> {
        private final Executor callbackExecutor;
        private final Call<T> delegate;

        // 注意这里的Call传递进来的是一个封装好的OkHttpCall类
        ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
            this.callbackExecutor = callbackExecutor;
            this.delegate = delegate;
        }

        @Override public void enqueue(Callback<T> callback) {
            delegate.enqueue(new ExecutorCallback<>(callbackExecutor, callback));
        }

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

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

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

    static final class ExecutorCallback<T> implements Callback<T> {
        private final Executor callbackExecutor;
        private final Callback<T> delegate;

        ExecutorCallback(Executor callbackExecutor, Callback<T> delegate) {
            this.callbackExecutor = callbackExecutor;
            this.delegate = delegate;
        }

        @Override public void onResponse(final Response<T> response, final Retrofit retrofit) {
            callbackExecutor.execute(new Runnable() {
                @Override public void run() {
                    delegate.onResponse(response, retrofit);
                }
            });
        }

        @Override public void onFailure(final Throwable t) {
            callbackExecutor.execute(new Runnable() {
                @Override public void run() {
                    delegate.onFailure(t);
                }
            });
        }
    }
}

可以看出来ExecutorCallbackCall也是一个代理类,它的委托类是OkHttpCall;所以使用默认的CallAdapterFactory返回的是一个封装了OkHttpCall的一个Call类,其具体的类型是ExecutorCallbackCall;

4)OkHttpCall:

final class OkHttpCall<T> implements Call<T> {
    private final Retrofit retrofit;
    private final RequestFactory requestFactory;
    private final Converter<ResponseBody, T> responseConverter;
    private final Object[] args;

    private volatile com.squareup.okhttp.Call rawCall;
    private boolean executed; // Guarded by this.
    private volatile boolean canceled;

    OkHttpCall(Retrofit retrofit, RequestFactory requestFactory,
               Converter<ResponseBody, T> responseConverter, Object[] args) {
        this.retrofit = retrofit;
        this.requestFactory = requestFactory;
        this.responseConverter = responseConverter;
        this.args = args;
    }

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

来看enqueue操作;在用户代码中:

call.enqueue(new Callback<UserInfo>() {
    @Override
    public void onResponse(Response<UserInfo> response, Retrofit retrofit) {
        UserInfo data = response.body();
        LogUtils.i("Call Result:" + data.m);
    }

    @Override
    public void onFailure(Throwable t) {
        LogUtils.e(t.toString());
    }
});

由前面知这里的Call对应的是一个ExecutorCallbackCall,来看起enqueue操作:

5)ExecutorCallbackCall#enqueue:

@Override
public void enqueue(Callback<T> callback) {
    delegate.enqueue(new ExecutorCallback<>(callbackExecutor, callback));
}

delegate对应的即是OkHttpCall,先来看其enqueue传入的参数: ExecutorCallback

static final class ExecutorCallback<T> implements Callback<T> {
    private final Executor callbackExecutor;
    private final Callback<T> delegate;

    ExecutorCallback(Executor callbackExecutor, Callback<T> delegate) {
        this.callbackExecutor = callbackExecutor;
        this.delegate = delegate;
    }

    @Override
    public void onResponse(final Response<T> response, final Retrofit retrofit) {
        callbackExecutor.execute(new Runnable() {
            @Override
            public void run() {
                delegate.onResponse(response, retrofit);
            }
        });
    }

    @Override
    public void onFailure(final Throwable t) {
        callbackExecutor.execute(new Runnable() {
            @Override public void run() {
                delegate.onFailure(t);
            }
        });
    }
}

ExecutorCallback也是一个代理类,用来封装用户定义的Callback,即类内部的变量delegate;callbackExecutor是查找Platform过程中new Android时创建的,其execute的逻辑较为简单,就是使用主线程对应的Handler来将Runnable事件post出去;可以看到,这里最终的响应都会在主线程中,而且调用用户自定义的onResponse和onFailure;

ExecutorCallback的主要作用就是封装Callback,将Callback的响应切换到主线程中;

6)继续来看对应的OkHttpCall的enqueue操作:

@Override
public void enqueue(final Callback<T> callback) {
    synchronized (this) {
        if (executed) throw new IllegalStateException("Already executed");
        executed = true;
    }

    // 注意okHttp的call和retrofit的Call是不同
    com.squareup.okhttp.Call rawCall;
    try {
        // 创建一个okhttp类型的Call
        rawCall = createRawCall();
    } catch (Throwable t) {
        callback.onFailure(t);
        return;
    }
    // 如果取消
    if (canceled) {
        rawCall.cancel();
    }
    this.rawCall = rawCall;

    // 将Call中事务全部委托给okHttp来操作
    // 调用okHttp的enqueue,使用okHttp的Callback来封装retrofit中的Callback
    rawCall.enqueue(new com.squareup.okhttp.Callback() {
        // 请求失败的响应
        private void callFailure(Throwable e) {
            try {
                callback.onFailure(e);
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }
        // 请求成功的响应
        private void callSuccess(Response<T> response) {
            try {
                callback.onResponse(response, retrofit);
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }

        @Override
        public void onFailure(Request request, IOException e) {
            callFailure(e);
        }

        @Override
        public void onResponse(com.squareup.okhttp.Response rawResponse) {
            Response<T> response;
            try {
                // 获得结果,并且解析结果
                response = parseResponse(rawResponse);
            } catch (Throwable e) {
                callFailure(e);
                return;
            }
            callSuccess(response);
        }
    });
}

OkHttpCall是对OkHttp里面的Call的封装,将所有的操作都委托给该Call进行操作;这里主要的是通过retrofit的call来创建一个okHttp的Call类;这里通过createRawCall来创建:

private com.squareup.okhttp.Call createRawCall() {
  return retrofit.client().newCall(requestFactory.create(args));
}

这里是通过okHttpClient来创建的一个Call;首先来看 requestFactory是如何根据args参数来创建一个相应的Call的;

先来看requestFactory,它是MethodHandler中创建传递过来的;

RequestFactory requestFactory = RequestFactoryParser.parse(method, responseType, retrofit);

(四)RequestFactory:

final class RequestFactoryParser {
    private final Method method;

    static RequestFactory parse(Method method, Type responseType, Retrofit retrofit) {
        RequestFactoryParser parser = new RequestFactoryParser(method);
        // Method对应的注解这里解析
        parser.parseMethodAnnotations(responseType);
        parser.parseParameters(retrofit);
        // 创建一个RequestFactory
        return parser.toRequestFactory(retrofit.baseUrl());
    }

    private RequestFactoryParser(Method method) {
        this.method = method;
    }
}

RequestFactoryParser主要是根据method对应的注解及返回类型进行相应解析,得出相应的解析结果,然后创建一个RequestFactory来保存所有解析后结果,供创建OkHttpCall来使用。

<一>parseMethodAnnotations:

1)RequestFactoryParser#parseMethodAnnotations:

// 这里是对注解进行解析的核心代码
// 根据注解类型的不同(即请求类型类型的不同进行相应解析)
// 这里也对应的retrofit的基本用法
private void parseMethodAnnotations(Type responseType) {
    for (Annotation annotation : method.getAnnotations()) {
        if (annotation instanceof DELETE) {
            parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
        } else if (annotation instanceof GET) {
            parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
        } else if (annotation instanceof HEAD) {
            parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
            if (!Void.class.equals(responseType)) {
                throw methodError(method, "HEAD method must use Void as response type.");
            }
        } else if (annotation instanceof PATCH) {
            parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
        } 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 HTTP) {
            HTTP http = (HTTP) annotation;
            parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
        } else if (annotation instanceof Headers) {
            // 只有Headers是通过parseHeaders来解析的
            String[] headersToParse = ((Headers) annotation).value();
            if (headersToParse.length == 0) {
                throw methodError(method, "@Headers annotation is empty.");
            }
            headers = parseHeaders(headersToParse);
        } else if (annotation instanceof Multipart) {
            // 可以看到Multipart和FormUrlEncoded不能同时定义
            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;
        }
    }

    if (httpMethod == null) {
        throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
    }
    // 如果不存在实体,但是用户定义为isMultipart或者isFormEncoded类型,则会抛出异常
    if (!hasBody) {
        if (isMultipart) {
            throw methodError(method,
                    "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
        }
        if (isFormEncoded) {
            throw methodError(method,
                    "FormUrlEncoded can only be specified on HTTP methods with request body "
                            + "(e.g., @POST).");
        }
    }
}

这里是对注解进行解析的核心代码 ,根据注解类型的不同(即请求类型类型的不同) 进行相应解析,这里也对应的retrofit的基本用法;

可以看到除了headers使用的parseheader进行解析外,其他都是通过 parseHttpMethodAndPath进行解析的;这里来重点分析下parseHttpMethodAndPath;

2)parseHttpMethodAndPath:

// 这个函数只是先做了一个前期判断
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);
    }
    // 对应"GET","POST"等
    this.httpMethod = httpMethod;
    // 标注有没有实体
    this.hasBody = hasBody;

    // 注解值为空直接返回
    if (value.isEmpty()) {
        return;
    }

    // 判断URL是否已经有查询字符串query string
    // Get the relative URL path and existing query string, if present.
    int question = value.indexOf(‘?‘);
    if (question != -1 && question < value.length() - 1) {
        // 保证URL的查询字符串中没有{...}之类的字符
        // 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);
        }
    }

    // 具体的解析继续由parsePathParameters来完成
    this.relativeUrl = value;
    this.relativeUrlParamNames = parsePathParameters(value);
}

这个函数仅是做了一个简单的前期判断,将method对应的请求类型(httpMethod) ,注解值(relativeUrl),以及是否包含实体信息(hasBody)赋值给该RequestFactoryParser;

来看POST和GET的简单调用实例:

parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);

parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);

继续来看解析函数parsePathParameters :

private static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*";
private static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM);
private static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}");
/**
 * Gets the set of unique path parameters used in the given URI. If a parameter is used twice
 * in the URI, it will only show up once in the set.
 */
// 检测出路径中所有{..}的字段,如{user}等,添加到一个Set中(因此不会重复添加)
static Set<String> parsePathParameters(String path) {
    Matcher m = PARAM_URL_REGEX.matcher(path);
    Set<String> patterns = new LinkedHashSet<>();
    while (m.find()) {
        patterns.add(m.group(1));
    }
    return patterns;
}

这一步仅是根据正则表达式获取URL中所有{…}类型的数据,添加到patterns这个Set中,然后返回给RequestFactoryParser,对relativeUrlParamNames进行赋值;

第一步解析完毕,来到第二步parseParameters:

<二>parseParameters:

private final Method method;
private void parseParameters(Retrofit retrofit) {
    Type[] methodParameterTypes = method.getGenericParameterTypes();
    // 获取method所有参数中的所有的注解信息
    Annotation[][] methodParameterAnnotationArrays = method.getParameterAnnotations();

    boolean gotField = false;
    boolean gotPart = false;
    boolean gotBody = false;
    boolean gotPath = false;
    boolean gotQuery = false;
    boolean gotUrl = false;

    int count = methodParameterAnnotationArrays.length;
    // 这里是一个重要的类
    RequestBuilderAction[] requestBuilderActions = new RequestBuilderAction[count];
    for (int i = 0; i < count; i++) {
        Type methodParameterType = methodParameterTypes[i];
        Annotation[] methodParameterAnnotations = methodParameterAnnotationArrays[i];
        if (methodParameterAnnotations != null) {
            for (Annotation methodParameterAnnotation : methodParameterAnnotations) {
                RequestBuilderAction action = null;
                // 解析URL
                if (methodParameterAnnotation instanceof Url) {
                    if (gotUrl) {
                        throw parameterError(i, "Multiple @Url method annotations found.");
                    }
                    if (gotPath) {
                        throw parameterError(i, "@Path parameters may not be used with @Url.");
                    }
                    if (gotQuery) {
                        throw parameterError(i, "A @Url parameter must not come after a @Query");
                    }
                    if (methodParameterType != String.class) {
                        throw parameterError(i, "@Url must be String type.");
                    }
                    if (relativeUrl != null) {
                        throw parameterError(i, "@Url cannot be used with @%s URL", httpMethod);
                    }
                    gotUrl = true;
                    action = new RequestBuilderAction.Url();

                } else if (methodParameterAnnotation instanceof Path) { // 解析Path注解
                    if (gotQuery) {
                        throw parameterError(i, "A @Path parameter must not come after a @Query.");
                    }
                    if (gotUrl) {
                        throw parameterError(i, "@Path parameters may not be used with @Url.");
                    }
                    if (relativeUrl == null) {
                        throw parameterError(i, "@Path can only be used with relative url on @%s",
                                httpMethod);
                    }
                    gotPath = true;

                    Path path = (Path) methodParameterAnnotation;
                    String name = path.value();
                    validatePathName(i, name);
                    action = new RequestBuilderAction.Path(name, path.encoded());

                } else if (methodParameterAnnotation instanceof Query) { // 解析Query注解
                    Query query = (Query) methodParameterAnnotation;
                    action = new RequestBuilderAction.Query(query.value(), query.encoded());
                    gotQuery = true;

                } else if (methodParameterAnnotation instanceof QueryMap) { // 解析QueryMap注解
                    if (!Map.class.isAssignableFrom(Utils.getRawType(methodParameterType))) {
                        throw parameterError(i, "@QueryMap parameter type must be Map.");
                    }
                    QueryMap queryMap = (QueryMap) methodParameterAnnotation;
                    action = new RequestBuilderAction.QueryMap(queryMap.encoded());

                } else if (methodParameterAnnotation instanceof Header) { // 解析header注解
                    Header header = (Header) methodParameterAnnotation;
                    action = new RequestBuilderAction.Header(header.value());

                } else if (methodParameterAnnotation instanceof Field) { // 解析Field注解
                    if (!isFormEncoded) {
                        throw parameterError(i, "@Field parameters can only be used with form encoding.");
                    }
                    Field field = (Field) methodParameterAnnotation;
                    action = new RequestBuilderAction.Field(field.value(), field.encoded());
                    gotField = true;

                } else if (methodParameterAnnotation instanceof FieldMap) { // 解析FieldMap
                    if (!isFormEncoded) {
                        throw parameterError(i, "@FieldMap parameters can only be used with form encoding.");
                    }
                    if (!Map.class.isAssignableFrom(Utils.getRawType(methodParameterType))) {
                        throw parameterError(i, "@FieldMap parameter type must be Map.");
                    }
                    FieldMap fieldMap = (FieldMap) methodParameterAnnotation;
                    action = new RequestBuilderAction.FieldMap(fieldMap.encoded());
                    gotField = true;

                } else if (methodParameterAnnotation instanceof Part) { // 解析Part
                    if (!isMultipart) {
                        throw parameterError(i, "@Part parameters can only be used with multipart encoding.");
                    }
                    Part part = (Part) methodParameterAnnotation;
                    com.squareup.okhttp.Headers headers = com.squareup.okhttp.Headers.of(
                            "Content-Disposition", "form-data; name=\"" + part.value() + "\"",
                            "Content-Transfer-Encoding", part.encoding());
                    Converter<?, RequestBody> converter;
                    try {
                        converter =
                                retrofit.requestConverter(methodParameterType, methodParameterAnnotations);
                    } catch (RuntimeException e) { // Wide exception range because factories are user code.
                        throw parameterError(e, i, "Unable to create @Part converter for %s",
                                methodParameterType);
                    }
                    action = new RequestBuilderAction.Part<>(headers, converter);
                    gotPart = true;

                } else if (methodParameterAnnotation instanceof PartMap) { //解析PartMap
                    if (!isMultipart) {
                        throw parameterError(i,
                                "@PartMap parameters can only be used with multipart encoding.");
                    }
                    if (!Map.class.isAssignableFrom(Utils.getRawType(methodParameterType))) {
                        throw parameterError(i, "@PartMap parameter type must be Map.");
                    }
                    PartMap partMap = (PartMap) methodParameterAnnotation;
                    action = new RequestBuilderAction.PartMap(retrofit, partMap.encoding(),
                            methodParameterAnnotations);
                    gotPart = true;

                } else if (methodParameterAnnotation instanceof Body) { // 解析Body
                    if (isFormEncoded || isMultipart) {
                        throw parameterError(i,
                                "@Body parameters cannot be used with form or multi-part encoding.");
                    }
                    if (gotBody) {
                        throw parameterError(i, "Multiple @Body method annotations found.");
                    }

                    Converter<?, RequestBody> converter;
                    try {
                        converter =
                                retrofit.requestConverter(methodParameterType, methodParameterAnnotations);
                    } catch (RuntimeException e) { // Wide exception range because factories are user code.
                        throw parameterError(e, i, "Unable to create @Body converter for %s",
                                methodParameterType);
                    }
                    action = new RequestBuilderAction.Body<>(converter);
                    gotBody = true;
                }

                if (action != null) {
                    if (requestBuilderActions[i] != null) {
                        throw parameterError(i, "Multiple Retrofit annotations found, only one allowed.");
                    }
                    requestBuilderActions[i] = action;
                }
            }
        }

        if (requestBuilderActions[i] == null) {
            throw parameterError(i, "No Retrofit annotation found.");
        }
    }

    if (relativeUrl == null && !gotUrl) {
        throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
    }
    if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
        throw methodError(method, "Non-body HTTP method cannot contain @Body.");
    }
    if (isFormEncoded && !gotField) {
        throw methodError(method, "Form-encoded method must contain at least one @Field.");
    }
    if (isMultipart && !gotPart) {
        throw methodError(method, "Multipart method must contain at least one @Part.");
    }

    this.requestBuilderActions = requestBuilderActions;
}

这里是根据method里面对应的参数中的注解比如@(Url,Path,Query,QueryMap,Header,Field,FieldMap,Part,PartMap,Body),它们的解析操作都是通过创建一个RequestBuilderAction类进行相应的解析,比如@Path,解析则调用的是创建一个RequestBuilderAction.Path,Path类是RequestBuilderAction的静态内部类,继承了RequestBuilderAction;最后所有参数中的注解对应一个RequestBuilderAction数组requestBuilderActions,把这个数组赋值给RequestFactoryParser;

abstract class RequestBuilderAction {
    abstract void perform(RequestBuilder builder, Object value);
}

RequestBuilderAction是个抽象类,它内部有一个perform的抽象方法;还有一些具体的内部类继承该方法,根据不同的注解,来创建不同的静态内部类,这些静态内部类都继承了RequestBuilderAction,并且重写了自己的perform方法;

如Path:

static final class Path extends RequestBuilderAction {
  private final String name;
  private final boolean encoded;

  Path(String name, boolean encoded) {
    this.name = checkNotNull(name, "name == null");
    this.encoded = encoded;
  }

  @Override void perform(RequestBuilder builder, Object value) {
    if (value == null) {
      throw new IllegalArgumentException(
          "Path parameter \"" + name + "\" value must not be null.");
    }
    builder.addPathParam(name, value.toString(), encoded);
  }
}

可以看到这里涉及到一个 RequestBuilder的概念,等到具体使用的时候再进行分析;

<三>parser.toRequestFactory(retrofit.baseUrl())

private RequestFactory toRequestFactory(BaseUrl baseUrl) {
  return new RequestFactory(httpMethod, baseUrl, relativeUrl, headers, contentType, hasBody,
      isFormEncoded, isMultipart, requestBuilderActions);
}

最后一步将所有解析完的信息封装成一个 RequestFactory;

则继续来看第(三)步中okHttp创建Call是传递进来的参数:requestFactory.create(args)

1)RequestFactory#create:

final class RequestFactory {
    private final String method;
    private final BaseUrl baseUrl;
    private final String relativeUrl;
    private final Headers headers;
    private final MediaType contentType;
    private final boolean hasBody;
    private final boolean isFormEncoded;
    private final boolean isMultipart;
    private final RequestBuilderAction[] requestBuilderActions;

    RequestFactory(String method, BaseUrl baseUrl, String relativeUrl, Headers headers,
                   MediaType contentType, boolean hasBody, boolean isFormEncoded, boolean isMultipart,
                   RequestBuilderAction[] requestBuilderActions) {
        this.method = method;
        this.baseUrl = baseUrl;
        this.relativeUrl = relativeUrl;
        this.headers = headers;
        this.contentType = contentType;
        this.hasBody = hasBody;
        this.isFormEncoded = isFormEncoded;
        this.isMultipart = isMultipart;
        this.requestBuilderActions = requestBuilderActions;
    }

    Request create(Object... args) {
        // 创建一个RequestBuilder,它是真正创建Request的类
        RequestBuilder requestBuilder =
                new RequestBuilder(method, baseUrl.url(), relativeUrl, headers, contentType, hasBody,
                        isFormEncoded, isMultipart);

        if (args != null) {
            // 前面解析method参数中的注解获取到的RequestBuilderAction
            RequestBuilderAction[] actions = requestBuilderActions;
            if (actions.length != args.length) {
                throw new IllegalArgumentException("Argument count ("
                        + args.length
                        + ") doesn‘t match action count ("
                        + actions.length
                        + ")");
            }
            for (int i = 0, count = args.length; i < count; i++) {
                // 这里调用RequestBuilderAction的perform进行创建
                actions[i].perform(requestBuilder, args[i]);
            }
        }

        // 建造者模型,返回一个build
        return requestBuilder.build();
    }
}

可以看到RequestFactory在create时创建了一个RequestBuilder,它是一个典型的Builder模式,也就是类似OkHttp的Request Buidler模式,由用户调用builder自定义来转化为通过注解方式进行定义,而Retrofit通过解析注解信息,分析用户行为,然后将解析信息添加到requestBuidler中来自行构造Request;它暴漏出注解定义的方式,而将具体的Request Builder细节隐藏了。

这里终点来看RequestBuidler,前面分析method参数类型获得的RequestBuilderAction,其具体的perform也是通过RequestBuilderAction来实现的;

<四>RequestBuilder:

final class RequestBuilder {
// 注意这里的Request对应的是okHttp的request
private final Request.Builder requestBuilder;
    RequestBuilder(String method, HttpUrl baseUrl, String relativeUrl, Headers headers,
                   MediaType contentType, boolean hasBody, boolean isFormEncoded, boolean isMultipart) {
this.method = method;
this.baseUrl = baseUrl;
this.relativeUrl = relativeUrl;
this.requestBuilder = new Request.Builder();
this.contentType = contentType;
this.hasBody = hasBody;

if (headers != null) {
requestBuilder.headers(headers);
        }

if (isFormEncoded) {
// Will be set to ‘body‘ in ‘build‘.
formEncodingBuilder = new FormEncodingBuilder();
        } else if (isMultipart) {
// Will be set to ‘body‘ in ‘build‘.
multipartBuilder = new MultipartBuilder();
            multipartBuilder.type(MultipartBuilder.FORM);
        }
    }
}

Retrofit默认是通过okHttp来实现的,RequestBuidler其实将所有Request创建的任务交给真正的类Okhttp中的Request.Builder进行构造器request;相应的FormEncodingBuilder以及MultipartBuilder也都是okHttp内部的;

RequestBuilderAction中的perform也都是通过RequestBuidler的函数来实现的,比如@Path:

static final class Path extends RequestBuilderAction {
    private final String name;
    private final boolean encoded;

    Path(String name, boolean encoded) {
       this.name = checkNotNull(name, "name == null");
       this.encoded = encoded;
   }

   @Override void perform(RequestBuilder builder, Object value) {
       if (value == null) {
       throw new IllegalArgumentException(
       "Path parameter \"" + name + "\" value must not be null.");
       }
       builder.addPathParam(name, value.toString(), encoded);
    }
}

可以看到调用的RequestBuilder的addPathParam方法:

void addPathParam(String name, String value, boolean encoded) {
    if (relativeUrl == null) {
    // The relative URL is cleared when the first query parameter is set.
    throw new AssertionError();
     }
    relativeUrl = relativeUrl.replace("{" + name + "}", canonicalize(value, encoded));
}

再来看RequestFactory#create的返回值,即RequestBuilder.builder:

Request build() {
  HttpUrl url;
  HttpUrl.Builder urlBuilder = this.urlBuilder;
  if (urlBuilder != null) {
    url = urlBuilder.build();
  } else {
    // No query parameters triggered builder creation, just combine the relative URL and base URL.
    url = baseUrl.resolve(relativeUrl);
  }

  RequestBody body = this.body;
  if (body == null) {
    // Try to pull from one of the builders.
    if (formEncodingBuilder != null) {
      body = formEncodingBuilder.build();
    } else if (multipartBuilder != null) {
      body = multipartBuilder.build();
    } else if (hasBody) {
      // Body is absent, make an empty body.
      body = RequestBody.create(null, new byte[0]);
    }
  }

  MediaType contentType = this.contentType;
  if (contentType != null) {
    if (body != null) {
      body = new ContentTypeOverridingRequestBody(body, contentType);
    } else {
      requestBuilder.addHeader("Content-Type", contentType.toString());
    }
  }

  return requestBuilder
      .url(url)
      .method(method, body)
      .build();
} 

可想而知最后调用的是okHttp总的builder来具体创建一个Request,具体的创建细节见okHttp源码解析;

因此返回的是一个okHttp中的Request;来看具体的创建:

retrofit.client().newCall(requestFactory.create(args));
OkHttpClient#newCall:
/**
 * Prepares the {@code request} to be executed at some point in the future.
 */
public Call newCall(Request request) {
    return new Call(this, request);
}

将Request封装成一个Call;因此,接下来的所有网络请求操作都交由okHttp进行处理;

(五)这里来看具体的对返回结果的转换:

在调用OkHttpCall的enqueue时,可以看到Callback中会对结果Response(okHttp中的)进行进一步解析,然后将解析后的结果通过Retrofit中定义的callback进行返回,返回的结果为Response:

rawCall.enqueue(new com.squareup.okhttp.Callback() {
        private void callFailure(Throwable e) {
            try {
                callback.onFailure(e);
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }

    private void callSuccess(Response<T> response) {
        try {
            callback.onResponse(response, retrofit);
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    @Override public void onFailure(Request request, IOException e) {
        callFailure(e);
    }

    @Override public void onResponse(com.squareup.okhttp.Response rawResponse) {
        Response<T> response;
        try {
            response = parseResponse(rawResponse);
        } catch (Throwable e) {
            callFailure(e);
            return;
        }
        callSuccess(response);
    }
});

可以看到主要解析过程则在于parseResponse中;

1)OkHttpCall#parseResponse:

private Response<T> parseResponse(com.squareup.okhttp.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.readBodyToBytesIfNecessary(rawBody);
            return Response.error(bufferedBody, rawResponse);
        } finally {
            closeQuietly(rawBody);
        }
    }

    // 没有数据返回情况,则不用进行解析
    if (code == 204 || code == 205) {
        return Response.success(null, rawResponse);
    }

    // ExceptionCatchingRequestBody是对okHttp的RequestBody类的一个封装
    ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
    try {
        // 利用变换器进行转换
        T body = responseConverter.convert(catchingBody);
        // 将转换后的实体结果和原Response封装成一个Response<T>
        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;
    }
}

当请求发生错误,获取204情况没有实体返回时,自然不用对实体进行转化;而对于实体的转换是通过最初定义的转换器来(这里用的是GSON)来进行covert的;然后将转换后的结果同原始okHttp返回的Response封装成一个Response进行返回;

先来看传递进来的转换器:

2)ConverterFactory:

是通过在build retrofit的时候添加的:

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://115.156.187.146/TransferServer/")
        .client(client)                                     // 添加okHttp
        .addConverterFactory(GsonConverterFactory.create()) // GSON进行转换
        .build();
Retrofit#ConverterFactory:
/** Add converter factory for serialization and deserialization of objects. */
public Builder addConverterFactory(Converter.Factory converterFactory) {
    converterFactories.add(checkNotNull(converterFactory, "converterFactory == null"));
    return this;
}

由前面的分析知,在创建MethodHandler时,

static MethodHandler<?> create(Retrofit retrofit, Method method) {
    CallAdapter<Object> callAdapter = (CallAdapter<Object>) createCallAdapter(method, retrofit);
    Type responseType = callAdapter.responseType();
    // 创建转换器
    Converter<ResponseBody, Object> responseConverter =
            (Converter<ResponseBody, Object>) createResponseConverter(method, retrofit, responseType);
    RequestFactory requestFactory = RequestFactoryParser.parse(method, responseType, retrofit);
    return new MethodHandler<>(retrofit, requestFactory, callAdapter, responseConverter);
}

private static Converter<ResponseBody, ?> createResponseConverter(Method method,
                                                                  Retrofit retrofit, Type responseType) {
    Annotation[] annotations = method.getAnnotations();
    try {
        return retrofit.responseConverter(responseType, annotations);
    } catch (RuntimeException e) { // Wide exception range because factories are user code.
        throw Utils.methodError(e, method, "Unable to create converter for %s", responseType);
    }
}

进而根据返回数据类型调用Retrofit.responseConverter来创建;下面基本上和CallAdapterFactory基本相同的流程;通过遍历converterFactories链表进行获取相应的解析Converter:

public <T> Converter<ResponseBody, T> responseConverter(Type type, Annotation[] annotations) {
    checkNotNull(type, "type == null");
    checkNotNull(annotations, "annotations == null");

    for (int i = 0, count = converterFactories.size(); i < count; i++) {
        // 重点看这个解析函数
        Converter<ResponseBody, ?> converter =
                converterFactories.get(i).fromResponseBody(type, annotations);
        if (converter != null) {
            //noinspection unchecked
            return (Converter<ResponseBody, T>) converter;
        }
    }

    StringBuilder builder = new StringBuilder("Could not locate ResponseBody converter for ")
            .append(type)
            .append(". Tried:");
    for (Converter.Factory converterFactory : converterFactories) {
        builder.append("\n * ").append(converterFactory.getClass().getName());
    }
    throw new IllegalArgumentException(builder.toString());
}

主要的逻辑在:

// 重点看这个解析函数
        Converter<ResponseBody, ?> converter =
                converterFactories.get(i).fromResponseBody(type, annotations);
这里的converterFactories.get(i)即是通过GsonConverterFactory.create()创建的GSON转换器;来看其具体细节;

3)GsonConverterFactory:

public final class GsonConverterFactory extends Converter.Factory {
  /**
   * Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
   * decoding from JSON (when no charset is specified by a header) will use UTF-8.
   */
  public static GsonConverterFactory create() {
    return create(new Gson());
  }

  /**
   * Create an instance using {@code gson} for conversion. Encoding to JSON and
   * decoding from JSON (when no charset is specified by a header) will use UTF-8.
   */
  public static GsonConverterFactory create(Gson gson) {
    return new GsonConverterFactory(gson);
  }

  private final Gson gson;

  private GsonConverterFactory(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
    this.gson = gson;
  }

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

  @Override public Converter<?, RequestBody> toRequestBody(Type type, Annotation[] annotations) {
    return new GsonRequestBodyConverter<>(gson, type);
  }
}

这个Factory很简单,就是持有了一个GSON实例对象;

上面调用了fromResponseBody,这里根据returntype来创建一个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 Type type;

    GsonRequestBodyConverter(Gson gson, Type type) {
        this.gson = gson;
        this.type = type;
    }

    @Override
    public RequestBody convert(T value) throws IOException {
        Buffer buffer = new Buffer();
        Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
        try {
            gson.toJson(value, type, writer);
            writer.flush();
        } catch (IOException e) {
            throw new AssertionError(e); // Writing to Buffer does no I/O.
        }
        return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
    }
}

其转换函数convert逻辑也较为简单,将工作交给gson就可以了;所以Retrofit的解析工作在okHttp的Call返回结果时,在其okHttp的Callback中进行解析,解析过程也较为简单,通过获取返回类型Returntype,然后使用gson进行解析即可;

时间: 2024-10-29 19:11:11

Retrofit源码解析的相关文章

带你一步步剖析Retrofit 源码解析:一款基于 OkHttp 实现的网络请求框架

OkHttp与Retrofit 的区别与联系是怎样的? 参考答案:OkHttp和Retrofit都是目前流行网络开源框架 封装不同:Retrofit封装了具体的请求,线程切换以及数据转换.retrofit通过使用代理,外观,策略模式对okhttp进行了封装OkHttp 是基于Http协议封装的一套请求客户端 职责不同:Retrofit主要负责应用层面的封装,面向开发者,方便使用,比如请求参数,响应数据的处理,错误处理等等.OkHttp主要负责socket部分的优化与封装,比如网络访问,多路复用,

Retrofit源码设计模式解析(上)

Retrofit通过注解的方法标记HTTP请求参数,支持常用HTTP方法,统一返回值解析,支持异步/同步的请求方式,将HTTP请求对象化,参数化.真正执行网络访问的是Okhttp,Okhttp支持HTTP&HTTP2,因此,使用Retrofit可以支持REST.HTTPS及SPDY. 行业内分析Retrofit的使用方法的文章已经比较丰富,这里不再赘述,如想了解这部分内容,请参考如下链接. <用 Retrofit 2 简化 HTTP 请求> <Retrofit 源码解析>

Retrofit源码设计模式解析(下)

本文将接着<Retrofit源码设计模式解析(上)>,继续分享以下设计模式在Retrofit中的应用: 适配器模式 策略模式 观察者模式 单例模式 原型模式 享元模式 一.适配器模式 在上篇说明CallAdapter.Factory使用工厂模式时,提到CallAdapter本身采用了适配器模式.适配器模式将一个接口转换成客户端希望的另一个接口,使接口本不兼容的类可以一起工作. Call接口是Retrofit内置的发送请求给服务器并且返回响应体的调用接口,包括同步.异步请求,查询.取消.复制等功

Android网络编程(十一)源码解析Retrofit

相关文章 Android网络编程(一)HTTP协议原理 Android网络编程(二)HttpClient与HttpURLConnection Android网络编程(三)Volley用法全解析 Android网络编程(四)从源码解析volley Android网络编程(五)OkHttp2.x用法全解析 Android网络编程(六)OkHttp3用法全解析 Android网络编程(七)源码解析OkHttp前篇[请求网络] Android网络编程(八)源码解析OkHttp后篇[复用连接池] Andr

Retrofit2源码解析

最近项目将网络框架换成Retrofit2.0.2,文中说的Retrofit都是指的Retrofit2这里要说明一下,毕竟和Retrofit1差别还是蛮大的,结合Okhttp,RxJava还是比较好用的,网上有很多前辈介绍过使用方法,本文是想研究一下Retrofit的源码.关于Retrofit的介绍可以查阅Retrofit的官方网站 直接进入主题:(注本文是结合RxJava介绍的,最好可以了解一下RxJava不了解也没有关系,大部分的思想是一样的) Retrofit的基本使用 Retrofit使用

Andriod OKHttp源码解析

前言:对于 OkHttp 勤快学QKXue.NET接触的时间其实不太长,一直都是使用Retrofit + OkHttp 来做网络请求的,但是有同学说面试的时候可能会问框架源码,这样光是会用是不够的,于是便萌生了通一通OkHttp源码的念头.经过大约一周的时间,源码看了个大概(说来惭愧,也就知道里面的原理),这里变向大家介绍一下我的所得,希望对大家能有所帮助.这里推荐两篇博文: OkHttp 官方教程解析 - 彻底入门 OkHttp 使用 和 拆轮子系列:拆 OkHttp 前者能够让你入门OkHt

Retrofit2 源码解析

原文链接:http://bxbxbai.github.io/2015/12/13/retrofit2-analysis/ 公司里最近做的项目中网络框架用的就是Retrofit,用的多了以后觉得这个框架真的非常好用,然后抽了点时间debug了一下源码,觉得不光代码写的非常好,而且设计这个框架的思路都非常特别,收获很多,决定记录下来 本文的源码分析基于Retrofit 2.0,和Retrofit 1.0有较大的不同, 本文主要分为几部分:0.Retrofit 是什么,1.Retrofit 怎么用,2

Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析

Java生鲜电商平台-SpringCloud微服务架构中网络请求性能优化与源码解析 说明:Java生鲜电商平台中,由于服务进行了拆分,很多的业务服务导致了请求的网络延迟与性能消耗,对应的这些问题,我们应该如何进行网络请求的优化与处理呢? 到底有没有一些好的建议与方案呢? 下面这个文章将揭晓上面的问题,让你对SpringCloud微服务网络请求性能有一个全新的认识. 目录简介 01.网络请求异常分类 02.开发中注意问题 03.原始的处理方式 04.如何减少代码耦合性 05.异常统一处理步骤 06

ChrisRenke/DrawerArrowDrawable源码解析

转载请注明出处http://blog.csdn.net/crazy__chen/article/details/46334843 源码下载地址http://download.csdn.net/detail/kangaroo835127729/8765757 这次解析的控件DrawerArrowDrawable是一款侧拉抽屉效果的控件,在很多应用上我们都可以看到(例如知乎),控件的github地址为https://github.com/ChrisRenke/DrawerArrowDrawable