您的位置:首页 > 其它

Retrofit源码解析---初始化

2016-11-03 16:20 393 查看
首先看下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来启动一个请求。下一篇我们分析请求的执行过程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: