ServiceMethod serviceMethod = Retrofit.this.loadServiceMethod(method); OkHttpCall okHttpCall = new OkHttpCall(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall);
loadServiceMethod is actually loading ServiceMethod, which corresponds to a network request method defined in our interface, such as getCall, which is finally handed over to OKHTTP.
ServiceMethod<?, ?> loadServiceMethod(Method method) { ServiceMethod<?, ?> result = serviceMethodCache.get(method); if (result != null) return result; // A thread synchronization lock is set, mainly to ensure the data security of our thread. synchronized (serviceMethodCache) { /** * Get our ServiceMethod, this ServiceMethod is created using the singleton mode, * It actually has a serveMethodCache buffer pool for acquisition. */ result = serviceMethodCache.get(method); /** * Non-empty judgment. If there is no cache, create a ServiceMethod object yourself, * It is created by the builder pattern Builder. */ if (result == null) { // Finally call build() to create the creation of our actual ServiceMethod object. result = new ServiceMethod.Builder<>(this, method).build(); /** * Put it in the cache pool, use the HTTP request method as the KEY, * The ServiceMethod object is stored in this buffer pool as VALUES. */ serviceMethodCache.put(method, result); } } return result; }
final class ServiceMethod<R, T> { // Upper and lower characters, digits, underscores, and hyphens, starting with a character. static final String PARAM = "[a-zA-Z][a-zA-Z0-9_-]*"; static final Pattern PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}"); static final Pattern PARAM_NAME_REGEX = Pattern.compile(PARAM); /** * network request factory, used to produce our network requests, * This call is actually our OKHTTP Call in Retrofit, * And OKHTTP Call is that Retrofit encapsulates it. It actually calls OKHTTP Call internally. */ private final okhttp3.Call.Factory callFactory; // Network request adapter, adapt our Call request to different platforms. For example: RxJava etc. private final CallAdapter<R, T> callAdapter; private final HttpUrl baseUrl; // Data converter. The function is to convert the data returned by the server to us into the java Bean objects we need. private final Converter<ResponseBody, R> responseConverter; // HTTP methods for network requests, such as: get, post, put, etc. private final String httpMethod; // The relative address of the network request. Relative address + baseUrl = absolute address of the network request. private final String relativeUrl; // Request headers for HTTP network requests. key-value pair. private final Headers headers; // The body type of the HTTP network request message. private final MediaType contentType; private final boolean hasBody; private final boolean isFormEncoded; private final boolean isMultipart; // method parameter handler, private final ParameterHandler<?>[] parameterHandlers;
The ServiceMethod object actually contains all the basic information we need to access the network. It is covered. The following is its constructor.
ServiceMethod(Builder<R, T> builder) { this.callFactory = builder.retrofit.callFactory(); this.callAdapter = builder.callAdapter; this.baseUrl = builder.retrofit.baseUrl (); this.responseConverter = builder.responseConverter; this.httpMethod = builder.httpMethod; this.relativeUrl = builder.relativeUrl; this.headers = builder.headers; this.contentType = builder.contentType; this.hasBody = builder.hasBody; this.isFormEncoded = builder.isFormEncoded; this.isMultipart = builder.isMultipart; this.parameterHandlers = builder.parameterHandlers; }
Next, let's take a look at the inner class Builder of ServiceMethod .
Builder(Retrofit retrofit, Method method) { this.retrofit = retrofit; // Get the network request method (get, post, etc.) this.method = method; // Get the annotations in the network request interface method this.methodAnnotations = method.getAnnotations(); // Get the type of the parameter in the network request interface method, it is a type. this.parameterTypes = method.getGenericParameterTypes(); // Get the complete content of the annotations in the network request interface method this.parameterAnnotationsArray = method.getParameterAnnotations(); }
Next, let's take a look at the above line of code: result = new ServiceMethod.Builder<>(this, method).build();
Finally call build() to create the creation of our actual ServiceMethod object.
private CallAdapter<T, R> createCallAdapter() { //Get the return type in the network request interface method. Type returnType = method.getGenericReturnType(); if (Utils.hasUnresolvableType(returnType)) { throw methodError( "Method return type must not include a type variable or wildcard: %s", returnType); } if (returnType == void.class) { throw methodError("Service methods cannot return void."); } //Get the annotations in the network request interface and call getAnnotations() in the reflection. Annotation[] annotations = method.getAnnotations(); try { //noinspection unchecked. callAdapter(return value, annotation type) return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations); } catch (RuntimeException e) { // Wide exception range because factories are user code. throw methodError(e, "Unable to create call adapter for %s", returnType); }