Android知识总结
一、ServiceMethod
ServiceMethod是一个负责转化(适配)的类,负责把一个接口的抽象方法的执行过程的结果转化(适配)成一个网络请求(HTTP call)。
1、ServiceMethod 内部参数
final class ServiceMethod {
// 用来校验的常量
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);
/**
* 网络请求工厂,用于生产我们的网络请求,
* 这个call在Retrofit当中其实就是我们的OKHTTP Call,
* 而OKHTTP Call呢就是Retrofit对它做了封装。它内部其实是调用了OKHTTP Call。
*/
private final okhttp3.Call.Factory callFactory;
// 网络请求适配器,把我们的Call请求适用于不同的平台。例如:RxJava等。
private final CallAdapter callAdapter;
//基础HttpUrl
private final HttpUrl baseUrl;
// 数据转换器。作用就是把服务器返回给我们的数据,转换成我们需要的java Bean对象。
private final Converter responseConverter;
// 网络请求的HTTP方法,比如:get, post, put等等。
private final String httpMethod;
// 网络请求的相对地址。 相对地址 + baseUrl = 网络请求的绝对地址。
private final String relativeUrl;
// HTTP网络请求的请求头。键值对。
private final Headers headers;
// HTTP网络请求报文的body类型。
private final MediaType contentType;
//是否有请求体
private final boolean hasBody;
//是否是表单提交
private final boolean isFormEncoded;
//以二进制流的方式提交
private final boolean isMultipart
// 方法参数处理器,
private final ParameterHandler>[] parameterHandlers;
...
}
2、ServiceMethod.Builder构造方法
//Retrofit
final Retrofit retrofit;
//定义接口的抽象方法
final Method method;
//定义接口的抽象方法上面的注解数组
final Annotation[] methodAnnotations;
//注解二维数组:第一维对应参数序列,第二维对应注解序列;
final Annotation[][] parameterAnnotationsArray;
// 参数类型数组
final Type[] parameterTypes;
// 响应的类型
Type responseType;
//是否有用 @Field 或者FieldMap 注解
boolean gotField;
//是否 有用@Part 或者 @PartMap注解
boolean gotPart;
//是否有用 @body注解
boolean gotBody;
// 是否 有用@Path 注解
boolean gotPath;
//是否 有用@Query 或者@QueryName 注解
boolean gotQuery;
// 是否具有url
boolean gotUrl;
//http 请求的方法
String httpMethod;
//是否 需要请求体
boolean hasBody;
//是否 使用@FormUrlEncoded 注解
boolean isFormEncoded;
// 是否 使用了@Multipart 注解
boolean isMultipart;
// 相对路径
String relativeUrl;
//请求头
Headers headers;
//类型
MediaType contentType;
//相对路径的url参数
Set relativeUrlParamNames;
//参数处理数组
ParameterHandler>[] parameterHandlers;
//响应转化器
Converter responseConverter;
//请求转化器
CallAdapter callAdapter;
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
// 获取网络请求方法(get,post等)
this.method = method;
// 获取网络请求接口方法里面的注解
this.methodAnnotations = method.getAnnotations();
// 获取网络请求接口方法里的参数的类型,它是一个types。
this.parameterTypes = method.getGenericParameterTypes();
// 获取网络请求接口方法里注解的完整内容
this.parameterAnnotationsArray = method.getParameterAnnotations()
}
- build()方法
public ServiceMethod build() {
// 查找能够适配返回类型的CallAdpater
callAdapter = createCallAdapter();
//获取方法的返回类型
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
//设置请求的数据适配器 converter
responseConverter = createResponseConverter();
// 解读方法的注解
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
if (!hasBody) {
if (isMultipart) {
throw methodError(
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}
return new ServiceMethod<>(this);
}
ServiceMethod#createCallAdapter
private CallAdapter createCallAdapter() {
//获取网络请求接口方法里的返回的类型。
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.");
}
//获取网络请求接口里的注解,调用的反射当中的getAnnotations()。
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked callAdapter(返回值, 注解类型)
return (CallAdapter) 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);
}
}
获取方法的返回类型默认调用ExecutorCallAdapterFactory#CallAdapter#responseType
方法:
@Override
public CallAdapter, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
//method方法返回值类型必须是Call
if (getRawType(returnType) != Call.class) {
return null;
}
//获取Call的泛型T的类型
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter
调用ServiceMethod#createResponseConverter
方法设置请求的数据适配器:
private Converter createResponseConverter(){
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create converter for %s", responseType);
}
}
调用ServiceMethod#parseMethodAnnotation
方法解读方法的注解:
private void parseMethodAnnotation(Annotation annotation) {
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("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 retrofit2.http.Headers) {
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError("@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError("Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError("Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
二、 OkHttpCall
OkHttpCall仅仅是一个包装类,外部使用Retrofit.Call,其实内部调用的是Okhttp3.Call,由OkHttpCall来实现调度。所以对外部来说,无需关心 网络层 倒是怎么操作的。在内部进行网络请求。
1、 分析成员变量
//方法处理类,后面详解讲解,大家这里有个印象即可
private final ServiceMethod serviceMethod;
//和方法处理类一样,其实是调用方法的入参,大家先知道就可以,后期会详细讲解。
private final Object[] args;
// 判断 是否已经取消了。
//volatile,如果有同学不清楚,请直接百度下,这个关键字还是很重要的,主要用于多线程使用的背景下。
private volatile boolean canceled;
// All guarded by this.
//真正的okhttp3.Call,真正的请求
private okhttp3.Call rawCall;
// 异常,包括IO和运行时异常
private Throwable creationFailure; // Either a RuntimeException or IOException.
//是否已经启动
private boolean executed;
2、执行异步请求
@Override public void enqueue(final Callback callback) {
checkNotNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true; // 标识该执行器正在执行
call = rawCall; // 得到OkHttp.call
failure = creationFailure;
if (call == null && failure == null) {
try {
call = rawCall = createRawCall(); //如果为空就创建OkHttp.call
} catch (Throwable t) {
failure = creationFailure = t;
}
}
}
if (failure != null) { // OkHttp.call 构造失败
callback.onFailure(this, failure);
return;
}
// 用户取消了执行器的执行
if (canceled) {
//去执行OkHttp.call 的取消行为
call.cancel();
}
//OkHttp.call 真正的执行过程
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callSuccess(Response response) {
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
3、执行同步请求
@Override public Response execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else {
throw (RuntimeException) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall(); //如果为空就创建OkHttp.call
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
//执行请求
return parseResponse(call.execute());
}
4、创建 okhttp3.Call
private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
三、RequestBuilder类
通过字面大家就能猜到了他是一个Request的builder类。这个Request是okhttp3.Request。
RequestBuilder这个类,主要就是用于创建一个okHttp的Request,里面有很多方法用于设置Request的一些参数。
1、变量分析
//请求类型,post或者get
private final String method;
//Http的url 根地址
private final HttpUrl baseUrl;
//相对路径的url,对应的是具体的接口
private String relativeUrl;
//HttpUrl的Builder
private HttpUrl.Builder urlBuilder;
//okHttp3里面的Request.Builder
private final Request.Builder requestBuilder;
// MediaType 也是okHttp3里面的MediaTyep。MediaType即是Internet Media Type,互联网
//媒体类型;也叫做MIME类型,在http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。
private MediaType contentType;
// 布尔类型,代表都是有body
private final boolean hasBody;
//okHttp3里面的MultipartBody的builder
private MultipartBody.Builder multipartBuilder;
//okHttp3里面的FormBody的builder
private FormBody.Builder formBuilder;
//okHttp3里面的RequestBody
private RequestBody body;
2、相关的set方法分析
- setRelativeUrl:设置相对路径的url
- addHeader:添加请求头
- addPathParam:添加PathParam参数
- addQueryParam:添加请求参数,如果是GET方法,直接拼接在相对路径上,如果是post方式则直接放到消息体,这里面其实通过okHttp3的HttpUrl.Builder来实现的。
- addFormField:添加表单,key-value键值对的形式
- addPart:这个方法有两个重载,一个是根据header和body来添加MultipartBody,另外一个是直接添加MultipartBody
- setBody:设置请求的bod
四、总结
一般的Retrofit网络请求的操作是指 Call.excute() & Call.enqueue()的过程,这个过程才是真正的网络请求,因为,网络配置,请求地址配置,Call适配,网络请求 requestBody &返回值responseBody转化适配准备工作都已经完成。
sharedListCall.enqueue(new Callback()...);
sharedListCall.excute();
在进行网络请求的执行的时候,基本上就是调用,ServiceMethod中设置的各个内容如 :
- 1)OkHttpCall进行网络请求,实则是进行okhttp的网络请求;
- 2)利用 converter进行网络请求数据的转换,一般是Gson();
- 3)利用 rxjava observable构建 rxjava类型的责任链访问方案,并进行线程切换;
- 如果没有rxjava的添加,那么就使用默认的callAdapter里面的callbackExecutor进行线程的切换, 进行网络请求.
整体网络请求的流程图请看下图: