Retrofit源码解析---初始化

来源:互联网 发布:照片冲印排版软件 编辑:程序博客网 时间:2024/05/17 22:18

首先看下demo

1、首先定义请求模版接口

public interface IServiceDemo {    @POST("login/nameAuth")    Call<String> login(            @Body User ueser);}
2、定义Retrofit类
        Retrofit retrofit = new Retrofit.Builder()                .baseUrl("http://123.56.186.199:8080/map-mobile/")                        //增加返回值为String的支持                .addConverterFactory(ScalarsConverterFactory.create())                        //增加返回值为Gson的支持(以实体类返回)                .addConverterFactory(GsonConverterFactory.create())                        //增加返回值为Oservable<T>的支持                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())                .build();

3、使用接口获取响应

IServiceDemo requestSerives = retrofit.create(IServiceDemo.class);//这里采用的是Java的动态代理模式        User user = new User();        user.setMobile("18508480922");        user.setPassword("111111");        Call<String> call = requestSerives.login(user);//传入我们请求的键值对的值        call.enqueue(new Callback<String>() {            @Override            public void onResponse(Call<String> call, Response<String> response) {                System.out.println("return:" + response.body().toString());            }            @Override            public void onFailure(Call<String> call, Throwable t) {                System.out.println("失败");            }        });

这一篇我们先看Retrofit的创建及接口的创建,下一篇看具体网络请求的执行,及先分析下面执行流程

       Retrofit retrofit = new Retrofit.Builder()                .baseUrl("http://123.56.186.199:8080/map-mobile/")                        //增加返回值为String的支持                .addConverterFactory(ScalarsConverterFactory.create())                        //增加返回值为Gson的支持(以实体类返回)                .addConverterFactory(GsonConverterFactory.create())                        //增加返回值为Oservable<T>的支持                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())                .build();        IServiceDemo requestSerives = retrofit.create(IServiceDemo.class);//这里采用的是Java的动态代理模式        User user = new User();        user.setMobile("18508480922");        user.setPassword("111111");        Call<String> call = requestSerives.login(user);//传入我们请求的键值对的值
1、首先我们看下Retrofit的创建
    public Builder() {      // 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());    }
Builder是Retrofit的一个内部类,这里会添加一个BuiltInConverters关于converterFactories后面会讲

   public Builder baseUrl(String baseUrl) {      checkNotNull(baseUrl, "baseUrl == null");      HttpUrl httpUrl = HttpUrl.parse(baseUrl);      if (httpUrl == null) {        throw new IllegalArgumentException("Illegal URL: " + baseUrl);      }      return baseUrl(httpUrl);    }
转化为HttpUrl,然后调用baseUrl

   public Builder baseUrl(final HttpUrl baseUrl) {      checkNotNull(baseUrl, "baseUrl == null");      List<String> pathSegments = baseUrl.pathSegments();      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);      }      return baseUrl(new BaseUrl() {        @Override public HttpUrl url() {          return baseUrl;        }      });    }
   public Builder baseUrl(BaseUrl baseUrl) {      this.baseUrl = checkNotNull(baseUrl, "baseUrl == null");      return this;    }
    public Builder addConverterFactory(Converter.Factory factory) {      converterFactories.add(checkNotNull(factory, "factory == null"));      return this;    }
添加converterFactories

    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {      adapterFactories.add(checkNotNull(factory, "factory == null"));      return this;    }

添加adapterFactories

最后调用build

 public Retrofit build() {      if (baseUrl == null) {        throw new IllegalStateException("Base URL required.");      }      okhttp3.Call.Factory callFactory = this.callFactory;      if (callFactory == null) {        callFactory = new OkHttpClient();      }      // Make a defensive copy of the adapters and add the default Call adapter.      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(callFactory, baseUrl, converterFactories, adapterFactories,          callbackExecutor, validateEagerly);    }

这里调用defaultCallAdapterFactory添加了一个默认的CallAdapter,最后使用前面的参数构造了一个Retrofit

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

2、接下来我们看Service的创建

IServiceDemo requestSerives = retrofit.create(IServiceDemo.class);/
 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);          }        });  }
这里使用了java的Proxy,最终方法的调用都会调用到这里的invoke方法。

3、Service方法调用

Call<String> call = requestSerives.login(user);
调用到前面的invoke

    @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);          }        });
前面两个条件不满足,最终调用loadMethodHandler(method).invoke(args);

先看loadMethodHandler(method)

  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;  }

首先查看该方法是否已经解析过,如果解析过直接返回,没有的话重新创建一个,然后添加到缓存,我们看下create方法

static MethodHandler create(Retrofit retrofit, Method method) {    CallAdapter<?> callAdapter = createCallAdapter(method, retrofit);    Type responseType = callAdapter.responseType();    if (responseType == Response.class || responseType == okhttp3.Response.class) {      throw Utils.methodError(method, "'"          + Types.getRawType(responseType).getName()          + "' is not a valid response body type. Did you mean ResponseBody?");    }    Converter<ResponseBody, ?> responseConverter =        createResponseConverter(method, retrofit, responseType);    RequestFactory requestFactory = RequestFactoryParser.parse(method, responseType, retrofit);    return new MethodHandler(retrofit.callFactory(), requestFactory, callAdapter,        responseConverter);  }
create方法做的事情比较多:

a)、解析Call适配器,这个适配器决定了整个调用的框架,如果是Call类型,则直接使用OkHttp的enque触发请求,而如果是Observable类型,则通过Subscribe出发请求,包括把最后的返回值转换为一个Observable

b)、创建返回值具体类型的Converter,如请求类型是自定义类型,则可能使用Gson转为Gson格式

c)、创建请求参数的RequestFactory ,包括请求的具体地址,请求方法,请求参数如何解析,是否有body等。

d)、根据前面解析的值创建一个MethodHandler。

下面我们分别来看

a、解析Call适配器

private static CallAdapter<?> createCallAdapter(Method method, Retrofit retrofit) {    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.");    }    Annotation[] annotations = method.getAnnotations();    try {      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);    }  }

获取返回值类型,判断返回值是否可以解析以及是否为void类型,获取方法上面的注解(请求路径及方法),然后调用callAdapter

  public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {    return nextCallAdapter(null, returnType, annotations);  }
 public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,      Annotation[] annotations) {    checkNotNull(returnType, "returnType == null");    checkNotNull(annotations, "annotations == null");    int start = adapterFactories.indexOf(skipPast) + 1;    for (int i = start, count = adapterFactories.size(); i < count; i++) {      CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);      if (adapter != null) {        return adapter;      }    }    StringBuilder builder = new StringBuilder("Could not locate call adapter for ")        .append(returnType)        .append(".\n");    if (skipPast != null) {      builder.append("  Skipped:");      for (int i = 0; i < start; i++) {        builder.append("\n   * ").append(adapterFactories.get(i).getClass().getName());      }      builder.append('\n');    }    builder.append("  Tried:");    for (int i = start, count = adapterFactories.size(); i < count; i++) {      builder.append("\n   * ").append(adapterFactories.get(i).getClass().getName());    }    throw new IllegalArgumentException(builder.toString());  }
nextCallAdapter从adapterFactories里选择一个合适的CallAdapter,对应Call是DefaultCallAdapterFactory,对应Observable是RxJavaCallAdapterFactory

这样CallAdapter就创建完了

b)、创建返回值具体类型的Converter

  private static Converter<ResponseBody, ?> createResponseConverter(Method method,      Retrofit retrofit, Type responseType) {    Annotation[] annotations = method.getAnnotations();    try {      return retrofit.responseBodyConverter(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);    }  }
获取注解,接着调用responseBodyConverter

 public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {    return nextResponseBodyConverter(null, type, annotations);  }

public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast,      Type type, Annotation[] annotations) {    checkNotNull(type, "type == null");    checkNotNull(annotations, "annotations == null");    int start = converterFactories.indexOf(skipPast) + 1;    for (int i = start, count = converterFactories.size(); i < count; i++) {      Converter<ResponseBody, ?> converter =          converterFactories.get(i).responseBodyConverter(type, annotations, this);      if (converter != null) {        //noinspection unchecked        return (Converter<ResponseBody, T>) converter;      }    }    StringBuilder builder = new StringBuilder("Could not locate ResponseBody converter for ")        .append(type)        .append(".\n");    if (skipPast != null) {      builder.append("  Skipped:");      for (int i = 0; i < start; i++) {        builder.append("\n   * ").append(converterFactories.get(i).getClass().getName());      }      builder.append('\n');    }    builder.append("  Tried:");    for (int i = start, count = converterFactories.size(); i < count; i++) {      builder.append("\n   * ").append(converterFactories.get(i).getClass().getName());    }    throw new IllegalArgumentException(builder.toString());  }

这里我们的具体类型是String,这里返回的Convert是ScalarsConverterFactory


c)、创建请求参数的RequestFactory

  static RequestFactory parse(Method method, Type responseType, Retrofit retrofit) {    RequestFactoryParser parser = new RequestFactoryParser(method);    Annotation[] methodAnnotations = method.getAnnotations();    parser.parseMethodAnnotations(responseType, methodAnnotations);    parser.parseParameters(retrofit, methodAnnotations);    return parser.toRequestFactory(retrofit.baseUrl());  }

获取方法的注解,调用parseMethodAnnotations解析方法的注解,调用parseParameters解析参数,最后调用toRequestFactory返回一个RequestFactory结构

先看parseMethodAnnotations

private void parseMethodAnnotations(Type responseType, Annotation[] methodAnnotations) {    for (Annotation annotation : methodAnnotations) {      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 OPTIONS) {        parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);      } else if (annotation instanceof HTTP) {        HTTP http = (HTTP) annotation;        parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());      } else if (annotation instanceof Headers) {        String[] headersToParse = ((Headers) annotation).value();        if (headersToParse.length == 0) {          throw methodError(method, "@Headers annotation is empty.");        }        headers = parseHeaders(headersToParse);      } else if (annotation instanceof Multipart) {        if (isFormEncoded) {          throw methodError(method, "Only one encoding annotation is allowed.");        }        isMultipart = true;      } else if (annotation instanceof FormUrlEncoded) {        if (isMultipart) {          throw methodError(method, "Only one encoding annotation is allowed.");        }        isFormEncoded = true;      }    }    if (httpMethod == null) {      throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");    }    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).");      }    }  }
这里对各种Http方法进行解析,我们这里是POST,最终调用

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

private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {    if (this.httpMethod != null) {      throw methodError(method, "Only one HTTP method is allowed. Found: %s and %s.",          this.httpMethod, httpMethod);    }    this.httpMethod = httpMethod;    this.hasBody = hasBody;    if (value.isEmpty()) {      return;    }    // Get the relative URL path and existing query string, if present.    int question = value.indexOf('?');    if (question != -1 && question < value.length() - 1) {      // Ensure the query string does not have any named parameters.      String queryParams = value.substring(question + 1);      Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);      if (queryParamMatcher.find()) {        throw methodError(method, "URL query string \"%s\" must not have replace block. "            + "For dynamic query parameters use @Query.", queryParams);      }    }    this.relativeUrl = value;    this.relativeUrlParamNames = parsePathParameters(value);  }
这里还会调用parsePathParameters对路径上的参数进行解析

  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;  }


接下来看parseParameters解析方法中的请求参数及注解

这个函数比较长,我们只看我们涉及到的一部分

Type[] parameterTypes = method.getGenericParameterTypes();    Annotation[][] parameterAnnotationsArray = method.getParameterAnnotations();
获取参数类型和注解

 for (int i = 0; i < count; i++) {      Type parameterType = parameterTypes[i];      if (Utils.hasUnresolvableType(parameterType)) {        throw parameterError(i, "Parameter type must not include a type variable or wildcard: %s",            parameterType);      }      Annotation[] parameterAnnotations = parameterAnnotationsArray[i];

for循环对请求参数和注解进行解析,我们这里注解的类型是Body

} else if (parameterAnnotation instanceof 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.requestBodyConverter(parameterType, parameterAnnotations,                  methodAnnotations);            } catch (RuntimeException e) { // Wide exception range because factories are user code.              throw parameterError(e, i, "Unable to create @Body converter for %s", parameterType);            }            action = new RequestAction.Body<>(converter);            gotBody = true;          }          if (action != null) {            if (requestActions[i] != null) {              throw parameterError(i, "Multiple Retrofit annotations found, only one allowed.");            }            requestActions[i] = action;          }
这里可以看到body不能和form or multi-part encoding一起使用,且Body注解只能有一个
   converter = retrofit.requestBodyConverter(parameterType, parameterAnnotations,                  methodAnnotations);
这里获取参数的convert解析器,和前面解析返回值具体类型的方式是一样的,不过这里我们是自定义类,返回的convert是GsonConverterFactory,把convert保存到requestActions[i]


最后是toRequestFactory方法

  private RequestFactory toRequestFactory(BaseUrl baseUrl) {    return new RequestFactory(httpMethod, baseUrl, relativeUrl, headers, contentType, hasBody,        isFormEncoded, isMultipart, requestActions);  }
这里根据前面的值创建一个RequestFactory

  RequestFactory(String method, BaseUrl baseUrl, String relativeUrl, Headers headers,      MediaType contentType, boolean hasBody, boolean isFormEncoded, boolean isMultipart,      RequestAction[] requestActions) {    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.requestActions = requestActions;  }

这样的话RequestFactory就创建好了,

d)、根据前面解析的值创建一个MethodHandler

  private MethodHandler(okhttp3.Call.Factory callFactory, RequestFactory requestFactory,      CallAdapter<?> callAdapter, Converter<ResponseBody, ?> responseConverter) {    this.callFactory = callFactory;    this.requestFactory = requestFactory;    this.callAdapter = callAdapter;    this.responseConverter = responseConverter;  }




回到前面的invoke方法,接着调用前面返回值(MethodHandler)的invoke方法

 Object invoke(Object... args) {    return callAdapter.adapt(        new OkHttpCall<>(callFactory, requestFactory, args, responseConverter));  }

这里使用前面的参数构造了一个OkHttpCall然后这里的callAdapter是DefaultCallAdapterFactory

@Override public <R> Call<R> adapt(Call<R> call) {        return call;      }
直接返回了call,也即我们刚创建的OkHttpCall

这样通过调用Service的方法,我们就获取到了一个OkHttpCall,OkHttpCall通过enqueue来启动一个请求。下一篇我们分析请求的执行过程。











0 0
原创粉丝点击