一、前言
Android的主要网络框架有:
网络框架 | 适用场景 |
---|---|
Retrofit | 根据okHttp封装的框架 |
okHttp | |
Volley | 2013年发布,适合数据量不大但通信频繁的场景,但不能下载文件 |
AsyncHttpClient | 基于HttpClient库的异步网络请求处理库,Android6.0之后不再推荐使用 |
备注 | Android中网络连接一般用socket和HTTP,HTTP请求比socket多,一般采用原生访问方式,如httpClient(android5.0后不推荐使用)\HttpUrlConnection |
主流的是Retrofit框架,且在项目开发中一直有用到,但是没有系统整理过其相关知识点,所以在这做个梳理。
二、retrofit的使用
第一步:在GitHub上查看最新的版本,然后添加库的依赖(由于Retrofit是基于OkHttp,所以还需要添加OkHttp库依赖)
api 'com.squareup.okhttp3:okhttp:3.11.0'
api 'com.squareup.retrofit2:retrofit:2.3.0'
api 'com.squareup.retrofit2:converter-gson:2.0.2'
第二步:添加权限
<uses-permission android:name="android.permission.INTERNET"/>
第三步:创建用于描述网络请求的接口
public interface HttpService {
@GET("openapi.do?keyfrom=abc&key=2032414398&type=data&doctype=json&version=1.1&q=car")
Call<ResponseBody> getCall(@Field("name") String name);
}
第四步:创建接收服务器返回数据的类(根据实际返回数据处理)
第五步:创建Retrofit实例并发送请求
首先,需要知道注解类型(网络请求方法 + 标记类 + 网络请求参数)及含义用法
A 网络请求方法
网络请求方法注解 | 说明 |
---|---|
@GET | 对应HTTP中网络请求的方法 |
@POST | 同上 |
@PUT | 同上 |
@DELETE | 同上 |
@PATH | 同上 |
@HEAD | 同上 |
@OPTIONS | 同上 |
@HTTP | 用于替换以上七个注解的作用 |
B 标记类
标记类注解名称 | 说明 |
---|---|
@FormUriEncoded | 表示请求体是一个Form表单 |
@MultiPart | 表示请求体是一个支持文件上传的Form表单 |
@Streaming | 表示返回的数据以流的形式返回:适用于返回数据较大的场景(其他情况默认将全部数据载入内存) |
C 网络请求参数
一般用的较多的是:@Path/@Query
网络请求参数注解名称 | 说明 |
---|---|
@Headers | 添加请求头 |
@Header | 添加不固定值的Header |
@Body | 用于非表单请求体 |
@Field | 向POST表单传入键值对 |
@FieldMap | 向POST表单传入键值对集合 |
@Part | 用于表单字段 |
@PartMap | 用于表单字段,适用于多文件上传 |
@Query | 查询参数的设置,功能同@Field,区别在于前者的数据体现在请求体上,而后者的体现在URL上 |
@QueryMap | 功能同@FieldMap |
@Path | URL缺省值,即动态的url访问 |
@URL | URL设置 |
具体代码实现:
通过Retrofit.create就可以拿到定义的HttpService 的实例,调用其方法即可拿到一个Call对象,通过call.enqueue即可完成异步的请求
// 创建Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("")
.addConverterFactory(GsonConverterFactory.create())
.build();
// 创建 网络请求接口 的实例——代理设计模式
HttpService httpService = retrofit.create(HttpService.class);
// 异步请求回调
Call<ResponseBody> call = httpService.getCall("");
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//请求处理,输出结果
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
// 失败处理
}
});
//同步请求
try {
Response<ResponseBody> response = call.execute();
// response.body().show();
} catch (IOException e) {
e.printStackTrace();
}
okHttp请求与Retrofit请求使用区别
okHttp的职责及存在问题,retrofit的优势
三、retrofit源码分析(retrofit:2.7.2)
网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装
3.1 创建过程
第一步:build
Retrofit通过build模式来生成一个Retrofit对象,Retrofit默认用OkHttp来发送网络请求。
Retrofit.java
public Retrofit build() {
// mark1
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
// mark2:默认只支持okhttp请求,不支持 httpurlconnection 和 httpclient
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
// mark3:添加一个线程管理 Executor,okhttp 切换线程需手动操作,但因为Executor 的存在retrofit 不要(实际是handler)
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// mark4:设置默认CallAdapterFactory
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// mark5:
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
mark2处代码:
初始化构建call 的工厂,但是这个地方直接使用了 okhttp的call,没有使用到工厂设计模式去添加构建httpclient 或者 httpurlconnection的方法来创建 call,说明retrofit 只支持okhttp创建call请求。
==》目的:创建一个OkHttpClient,换句话说,这里的调用就是生产 Okhttp网络请求需要的请求Call的,以备后面进行真正的网络请求。
mark3处代码:
网络请求需要在子线程中执行需要线程管理,通过源码分析知道实际上是运用handler进行线程切换,当网络请求回来了进行线程切换
==》目的:构建一个用handler封装的Executor,以备后面进行网络请求成功后的线程切换用
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
mark4处代码:
此处添加的CallAdapterFactory属于系统默认的,当然,我们可以添加RxJavaCallAdapterFactory。默认的CallAdapterFactory是 ExecutorCallAdapterFactory 类的对象
List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
return hasJava8Types
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
配置对象 | 作用 |
---|---|
baseUrl | 网络请求的url地址 |
callFactory | 网络请求工厂 |
callbackExecutor | 回调方法执行器 :默认是个handler,用于后续在网络请求中进行返回结果的线程自动切换 |
adapterFactories | 网络请求适配器工厂的集合?:DefaultCallAdapterFactory是对callbackExecutor的封装, |
converterFactories | 数据转换器工厂的集合:一般情况下用的最多的converter是GSON |
以上构建的Retrofit都是用于进行后面请求的需要的内容的一个准备工作。也就是封装Okhttp需要的准备工作。
第二步:create
create中使用了动态代理的技术方案,动态代理是运行时生效的
public <T> T create(final Class<T> service) {
validateServiceInterface(service);
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
// 通过动态代理的方式生成具体的网络请求实体对象
new InvocationHandler() {// 统一处理所有的请求方法
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override public @Nullable Object invoke(Object proxy, Method method,
@Nullable 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);
}
// 生成ServiceMethod对象(内部会将生成的ServiceMethod放入在缓存中,若已生成过则直接从缓存中获取)
// ServiceMethod—HttpServiceMethod
// ——根据ServiceMethod对象和请求参数生成一个OkHttpCall对象,其调用OkHttp的接口发起网络请求
//—— 调用serviceMethod的callAdapter的adapt方法,并传入okHttpCall,返回一个对象
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
loadServiceMethod() 解析接口
——解析接口之后返回的对象是ServiceMethod,从缓存中获取ServiceMethod对象,如果之前解析过,则直接从serviceMethodCache取出直接返回,否则调用ServiceMethod.parseAnnotations方法进行解析并将其放入缓存中。
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
ServiceMethod 抽象类的parseAnnotations方法
ServiceMethod.java
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
// 重点1
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
// 重点2:HttpServiceMethod
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
重点1:RequestFactory负责解析接口并且生成Request,继续看RequestFactory的 parseAnnotations方法
RequestFactory.java
/**RequestFactory 类的parseAnnotations方法**/
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
/**RequestFactory 类的build方法**/
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
//解析网络请求方法注解
parseMethodAnnotation(annotation);
}
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).");
}
}
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
//方法参数注解的解析
parameterHandlers[p] =
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
}
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.");
}
return new RequestFactory(this);
}
以上parseMethodAnnotation中又调用了 ——》parseHttpMethodAndPath——》parsePathParameters,整个流程解析了网络请求注解。
还有接口方法参数注解的解析,继续看RequestFactory中的parseParameter——》parseParameterAnnotation——》ParameterHandler.apply()——》RequestBuilder.addPathParam()
private @Nullable ParameterHandler<?> parseParameter(
int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
ParameterHandler<?> result = null;
if (annotations != null) {
for (Annotation annotation : annotations) {
ParameterHandler<?> annotationAction =
parseParameterAnnotation(p, parameterType, annotations, annotation);
if (annotationAction == null) {
continue;
}
if (result != null) {
throw parameterError(method, p,
"Multiple Retrofit annotations found, only one allowed.");
}
result = annotationAction;
}
}
if (result == null) {
if (allowContinuation) {
try {
if (Utils.getRawType(parameterType) == Continuation.class) {
isKotlinSuspendFunction = true;
return null;
}
} catch (NoClassDefFoundError ignored) {
}
}
throw parameterError(method, p, "No Retrofit annotation found.");
}
return result;
}
RequestBuilder.java
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();
}
String replacement = canonicalizeForPath(value, encoded);
String newRelativeUrl = relativeUrl.replace("{" + name + "}", replacement);
if (PATH_TRAVERSAL.matcher(newRelativeUrl).matches()) {
throw new IllegalArgumentException(
"@Path parameters shouldn't perform path traversal ('.' or '..'): " + value);
}
relativeUrl = newRelativeUrl;
}
以上,RequestFactory 类的parseParameter方法通过遍历参数注解,调用parseParameterAnnotation方法获取了注解中定义的参数值(path.value()),最后返回了new ParameterHandler.Path<>对象,在ParameterHandler类的Path实现中调用RequestBuilder类(创建请求)的addPathParam方法最终将相对路径relativeUrl的占位符通过描述网络请求接口方法传递的参数替换掉得到正确的相对路径relativeUrl。
而得到正确相对路径的RequestBuilder对象创建则在RequestFactory类的create方法中。
RequestFactory.java
okhttp3.Request create(Object[] args) throws IOException {
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
int argumentCount = args.length;
if (argumentCount != handlers.length) {
throw new IllegalArgumentException("Argument count (" + argumentCount
+ ") doesn't match expected count (" + handlers.length + ")");
}
// mark:得到正确相对路径的RequestBuilder对象创建
RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl,
headers, contentType, hasBody, isFormEncoded, isMultipart);
if (isKotlinSuspendFunction) {
// The Continuation is the last parameter and the handlers array contains null at that index.
argumentCount--;
}
List<Object> argumentList = new ArrayList<>(argumentCount);
for (int p = 0; p < argumentCount; p++) {
argumentList.add(args[p]);
handlers[p].apply(requestBuilder, args[p]);
}
return requestBuilder.get()
.tag(Invocation.class, new Invocation(method, argumentList))
.build();
}
重点2 :HttpServiceMethod.parseAnnotations()
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;
Annotation[] annotations = method.getAnnotations();
Type adapterType;
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType = Utils.getParameterLowerBound(0,
(ParameterizedType) parameterTypes[parameterTypes.length - 1]);
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response<T>.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
} else {
// TODO figure out if type is nullable or not
// Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
// Find the entry for method
// Determine if return type is nullable or not
}
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
adapterType = method.getGenericReturnType();
}
// mark1:最终通过retrofit对象拿到默认CallAdapter.Factory对象(ExecutorCallAdapterFactory)
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
if (responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (responseType == Response.class) {
throw methodError(method, "Response must include generic type (e.g., Response<String>)");
}
// TODO support Unit for Kotlin?
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
// mark2:最终通过retrofit拿到设置的Converter.Factory对象(我们设置了GsonConverterFactory)
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}
经分析知retrofit的create方法中loadServiceMethod(method)方法实际上就是HttpServiceMethod对象。
mark1:parseAnnotations方法中的createCallAdapter
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
try {
//noinspection unchecked
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create call adapter for %s", returnType);
}
}
Retrofit.callAdapter()
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
/**Retrofit 类的nextCallAdapter方法**/
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
Objects.requireNonNull(returnType, "returnType == null");
Objects.requireNonNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.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(callAdapterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
以上流程是HttpServiceMethod通过自身createCallAdapter调用Retrofit 类的callAdapter方法,而Retrofit 类的callAdapter方法又调用 Retrofit 类的nextCallAdapter方法遍历callAdapterFactories来得到CallAdapter.Factory对象;
前面分析知retrofit对象创建时Platform对象中提供了默认的CallAdapter.Factory对象为DefaultCallAdapterFactory(ExecutorCallAdapterFactory?),该对象也就是HttpServiceMethod的createCallAdapter方法得到的CallAdapter.Factory对象。
mark2:parseAnnotations方法中的createResponseConverter
private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create converter for %s", responseType);
}
}
Retrofit.responseBodyConverter()
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
Objects.requireNonNull(type, "type == null");
Objects.requireNonNull(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());
}
同理,HttpServiceMethod的createResponseConverter最终通过retrofit的nextResponseBodyConverter方法得到了Converter(GsonRequestBodyConverter)对象(我们设置了GsonConverterFactory.responseBodyConverter的方法创建了该对象)
所以,综上所有分析,代理的invoke方法中返回了loadServiceMethod(method).invoke(args != null ? args : emptyArgs)这一句代码,当retrofit.create生成的的接口对象调用其中的接口的方法,则会触发动态代理执行invoke方法,最终返回loadServiceMethod(method).invoke,也就是执行了
HttpServiceMethod.invoke()
@Override final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
此处的callAdapter经之前分析已知道是默认添加的ExecutorCallAdapterFactory对象。
查看DefaultCallAdapterFactory(ExecutorCallAdapterFactory?)源码可知(和RxJava2CallAdapterFactory什么区别):
DefaultCallAdapterFactory.java
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException(
"Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
}
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
? null
: callbackExecutor;
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return executor == null
? call
: new ExecutorCallbackCall<>(executor, call);
}
};
}
- 1.通过DefaultCallAdapterFactory(ExecutorCallAdapterFactory?)的adapt方法得到的Call对象就是ExecutorCallbackCall
- 2.ExecutorCallbackCall的enqueue方法执行在主线程,callbackExecutor就是Platfrom默认添加的MainThreadExecutor(Android环境中),所以callback.onResponse中随意更新UI
- 3.delegate对象就是OkHttpCall对象,所以我们Call执行的enqueue和execute方法都是OkHttpCall对象对象的enqueue和execute方法。
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(() -> {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
}
});
}
@Override public boolean isExecuted() {
return delegate.isExecuted();
}
@Override public Response<T> execute() throws IOException {
return delegate.execute();
}
@Override public void cancel() {
delegate.cancel();
}
@Override public boolean isCanceled() {
return delegate.isCanceled();
}
@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
@Override public Call<T> clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override public Request request() {
return delegate.request();
}
}
3.2 Retrofit adapter适配过程
适配器模式做为两个不同的接口之间的桥梁,使得Retrofit2.Call接口可以使用OKHttp.Call的实现来执行网络请求,其适配器就是CallAdapter.Factory
具体流程见上面HttpServiceMethod.parseAnnotations()种mark1处的分析~~~
3.3 Retrofit converter
——ResponseBody转化为Bean的过程
——其他数据转化成RequestBody的过程
3.4 retrofit设计模式(9种)
四、retrofit的实际应用
一般会与 RxJava 一起使用,后续会添加 RxJava 的知识汇总,到时再贴上链接。。