前言:这篇网络系列的初衷是分享下网络相关的知识,文章属于个人的学习总结博客。部分内容来源网络,如有不适,请私聊。
Android之网络—第一篇(Http原理)
Android之网络—第二篇(Https原理)
Android之网络—第三篇(解读OkHttp)
Android之网络—第四篇(解读Retrofit)
详解网络封装艺术之Retrofit
前面大概分析了下OkHttp,知道OkHttp更多的是网络的底层实现。使用起来的话,还需要各种定制化的配置,以及数据的解析,数据回调的线程线程切换等问题。但是这些问题在Retrofit中得到了更好的支持,Retrofit通过使用大量的设计模式很好解耦和封装了网络请求,使用起来更加舒适。
retrofit源码地址
简单介绍下Retrofit的使用
可以看看官网的实例介绍,链接地址:http://square.github.io/retrofit/
第一步,定义一个接口,并通过注解定义对应的Api实现。
public interface GithubService {
@GET("users/{user}/repos")
Call> listRepos(@Path("user") String user);
}
第二步,配置Retrofit对象,并创建接口对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
第三步,调用Api,传入实际参数,并开始请求
Call> repos = service.listRepos("octocat");
repos.enqueue(new Callback>() {
@Override
public void onResponse(Call> call, Response> response) {
System.out.println("response:"+response.body().get(0).getName());
}
@Override
public void onFailure(Call> call, Throwable t) {
}
});
这里的使用需要注意的点:定义接口通过注解定义对应的Api实现时,不同的注解有不同的使用方式。下面简单分析下。
上面通过注解@GET和@Path将真正的请求连接https://api.github.com/users/octocat/repos分别分割拼装起来了。Url = baseUrl() + path (完整URL = 基础域名 + 注解配置)
Retrofit注解说明
第一类:网络请求方法类型
- a、@GET、@POST、@PUT、@DELETE、@HEAD、@OPTIONS 分别对应
HTTP请求头的[Method]
- b、@HTTP 用于替换上述七种方式,可以通过属性
method
、path
、hasBody
进行设置。例如:
public interface GithubService {
@HTTP(method = "GET", path = "users/{user}/repos", hasBody = false)
Call> listRepos(@Path("user") String user);
}
第二类:标记类型,用于区分数据类型,对应HTTP的Content-Type类型
- a、@FormUrlEncoded 表示以普通表单类型提交数据,参数键值对需要用
@Filed
设置。例如:
public interface GithubService {
@FormUrlEncoded
@POST("user/edit")
Call updateUser(@Field("first_name") String first, @Field("last_name") String last);
}
- b、@Multipart 表示以多媒体类型提交数据,参数键值对需要用
@Part
设置。例如:
public interface GithubService {
@Multipart
@PUT("user/photo")
Call updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
}
第三类:请求参数类型,用于拼装请求参数
- a、@Header & @Headers 添加请求头。例如:
public interface GithubService {
@GET("user")
Call getUser(@Header("Authorization") String authorization)
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call getUser(@Path("username") String username);
// 区别在于使用场景和使用方式:
// 1. 使用场景:@Header用于添加不固定的请求头,@Headers用于添加固定的请求头
// 2. 使用方式:@Header作用于方法的参数;@Headers作用于方法
}
b、@Path 替换Url地址的缺省值。
c、@Query和@QueryMap 用于GET请求拼接?后的Key-Value参数。格式:https://www.baidu.com/?tn=98012088_10_dg&ch=3 例如:
public interface GithubService {
@GET("group/{id}/users")
Call> groupList(@Path("id") int groupId, @Query("sort") String sort);
@GET("group/{id}/users")
Call> groupList(@Path("id") int groupId, @QueryMap Map options);
}
- d、@Field & @FieldMap 用于@FormUrlEncoded 提交数据类型,拼接参数。例如:
public interface GithubService {
@FormUrlEncoded
@POST("user/edit")
Call updateUser(@Field("first_name") String first, @Field("last_name") String last);
@FormUrlEncoded
@POST("user/edit")
Call updateUser(@FieldMap Map map);
}
- e、@Part & @PartMap 用于@Multipart提交数据类型,拼接参数。例如:
public interface GithubService {
@Multipart
@PUT("user/photo")
Call updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
@Multipart
@PUT("user/photo")
Call updateUser(@PartMap Map args);
}
- f、@Body 用于以 Post方式 传递自定义数据类型给服务器。例如:
public interface GithubService {
@POST("users/new")
Call createUser(@Body User user);
}
源码解读Retrofit
public class Demo{
Retrofit retrofit = new Retrofit.Builder().build();
GitHubService service = retrofit.create(GitHubService.class);
Call> repos = service.listRepos("octocat").enqueue();
}
回归最开始的示例,让我们一步一步地去探究源码的实现吧
第一部分:Retrofit网络请求流程分析
(1)、动态代理调用ServerInterface接口
PS:动态代理可参考文章:说说 Java 代理模式
public final class Retrofit {
.....
public T create(final Class service) {
Utils.validateServiceInterface(service); //判断是否是接口类型
if (validateEagerly) { //是否预先加载ServiceInterface内的Api
eagerlyValidateMethods(service);
}
//通过动态代理加载Api接口
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get(); //平台 android / java8
private final Object[] emptyArgs = new Object[0];
@Override public 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) { //如果是Object对象的方法直接调用
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//通过ServerInterface的接口
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
ServiceMethod> loadServiceMethod(Method method) {
//内置一个缓存Map来缓存ServerInterface的接口
ServiceMethod> result = serviceMethodCache.get(method); //返回一个ServiceMethod对象
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;
}
.....
}
通过上述的源码分析发下,Retrofit 通过动态代理的方式调用ServerInterface接口实现。但是invoke()的具体调用又在哪里呢?
(2)、ServiceMethod解析注解并返回核心封装类HttpServiceMethod()
abstract class ServiceMethod {
static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
//通过RequestFactory将Api的注解解析成完整的请求连接
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.");
}
//传入解析后的requestFactory并返回具体子类对象
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
//抽象类,通过子类实现
abstract T invoke(Object[] args);
}
通过这里可以发现,ServiceMethod主要通过RequestFactory将注解解析成完整的请求格式,并返回子类HttpServiceMethod对象。
final class HttpServiceMethod extends ServiceMethod {
static HttpServiceMethod parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
//返回适配器对象
CallAdapter callAdapter = createCallAdapter(retrofit, method);
//异常判断
Type responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
//返回数据解析器对象
Converter responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory; //实际默认创建一个new OkHttpClient()实例
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
......
//callAdapter.adapt() 返回的就是Call对象。
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
}
(3)、网络请求具体实现OkHttpCall()
final class OkHttpCall implements Call {
......
//网络的同步请求
@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 if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall(); //创建OkHttpClient请求
} catch (IOException | RuntimeException | Error e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
}
//取消请求
if (canceled) {
call.cancel();
}
//返回请求结果,实际就是client.newCall(request).execute()发送请求
return parseResponse(call.execute());
}
......
//发送异步请求
@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;
failure = creationFailure;
if (call == null && failure == null) {
try {
call = rawCall = createRawCall(); //创建OkHttpClient请求
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
//取消请求
if (canceled) {
call.cancel();
}
//OkHttp发送异步请求,并返回结果
call.enqueue(new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
@Override
public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
......
//实际返回的就是OkHttp的RealCall对象,callFactory为OkHttpClient
private okhttp3.Call createRawCall() throws IOException {
//将注解的请求信息requestFactory,拼接到OkHttp配置里
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
.......
}
到这里就整体发现Retrofit的网络请求是通过封装OkHttp去做底层的请求的。整体的网络请求流程就分析完毕了。但是也没感觉到封装艺术的魅力呀。
第二部分:Retrofit封装艺术的魅力
前文介绍Retrofit时,注意赞美的词的关键点哈:处理繁琐的定制化的配置,随心所欲的定制化数据的解析,便捷的线程切换。但是,通过上面整个网络请求的分析,怎么没感觉到呢?
先来看看上面分析流程的几个关键点:
//1、通过RequestFactory将Api的注解解析成完整的请求连接
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
//2、获取并传入一系列初始化对象
new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
//3、通过适配器转换,做不同的线程策略切换
callAdapter.adapt(new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
//4、通过适配器转换,完成不同类型数据解析
response = parseResponse(rawResponse);
通过这几个关键点的分析,似乎好像触摸到什么有趣的东西哈。
- 第一点可以自动化的解析注解的配置,在写请求时就不需要关心繁琐的配置啦
- 第三点通过适配转化,就可以自动化完成线程的切换,在写请求时直接才主线程请求,数据也可以直接返回主线程啦
- 第四点通过适配转化,就可以将服务端请求的字节流请求转化为对应的数据格式,在写请求时直接解析数据就可以啦。
(1)Retrofit整体的网络架构图
架构图分析说明:
注意:上图的关键关于适配器模式部分,需要结合官方推荐的一起看,在Gradle添加依赖。
- 请求适配器(CallAdapter)
Java8 : com.squareup.retrofit2:adapter-java8:2.0.2
Guava : com.squareup.retrofit2:adapter-guava:2.0.2
Rxjava : com.squareup.retrofit2:adapter-rxjava:2.0.2
- 数据解析器(Converter)
Gson : com.squareup.retrofit2:converter-gson:2.0.2
Jackson : com.squareup.retrofit2:converter-jackson:2.0.2
Simple XML : com.squareup.retrofit2:converter-simplexml:2.0.2
Protobuf : com.squareup.retrofit2:converter-protobuf:2.0.2
Moshi : com.squareup.retrofit2:converter-moshi:2.0.2
Wire : com.squareup.retrofit2:converter-wire:2.0.2
Scalars : com.squareup.retrofit2:converter-scalars:2.0.2
(2)结合源码分析整体架构
通过整体架构分析发现,关键点的地方有三个:
- 1、CreateServerMethod() 这里为请求做准备工作都具体做了什么?
- 2、CallAdapter.Factory 这里是如何通过代码结构做到框架的适配转化?
- 3、Converter.Factory 这里是如何通过代码结构做到不同数据的适配的?
(1)、准备工作之解析注解
final class RequestFactory {
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
......
RequestFactory build() {
//遍历注解并解析
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
//一堆的异常判断
......
return new RequestFactory(this);
}
......
//根据请求头的Method注解分别对应解析
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);
} 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(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; //将Multipart标记
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isFormEncoded = true; //将FormEncod标记
}
}
}
总结来说,RequestFactory内部通过遍历注解,根据请求的Method的类型分别将网络注解参数获取并拼接,提供给OkHttp发起请求时直接用。
(2)、准备工作之请求适配器(CallAdapter)与 数据解析器(Converter)
请求适配器(CallAdapter)的基本代码结构:
public interface CallAdapter {
.....
//将传进来的Call转化为另一个Call
T adapt(Call call);
//定义抽象接口,用于标记持有适配器对象
abstract class Factory {
public abstract CallAdapter, ?> get(); //返回一个适配器
}
}
自定义的适配器对象:
class CustomCallAdapterFactory extends CallAdapter.Factory {
@Override
public @Nullable CallAdapter, ?> get(){
return new CallAdapter
数据解析器(Converter)的基本代码结构:
public interface Converter {
.....
//将解析的结果返回
T convert(F value) throws IOException;
//定义抽象接口,用于标记持有解析器对象
abstract class Factory {
//解析为Response
public Converter responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return null;
}
//解析为Request
public Converter, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,
Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
//解析为String类型数据
public Converter, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return null;
}
}
}
自定义的适配器对象:
class CustomConverterFactory extends Converter.Factory {
@Override
public Converter responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return new CustomResponseBodyConverter<>();
}
@Override
public Converter, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,
Annotation[] methodAnnotations, Retrofit retrofit) {
return new CustomRequestBodyConverter<>();
}
}
来看看Retrofit的源码默认的实现
final class HttpServiceMethod extends ServiceMethod {
static HttpServiceMethod parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
CallAdapter callAdapter = createCallAdapter(retrofit, method);
......
Converter responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
private static CallAdapter createCallAdapter(
Retrofit retrofit, Method method) {
Type returnType = method.getGenericReturnType();
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
//通过retrofit实例返回一个适配器
return (CallAdapter) 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);
}
}
private static Converter createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
//返回一个responseBody的数据解析器
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的具体实现
public final class Retrofit {
......
public CallAdapter, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public Converter responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public CallAdapter, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
//遍历List,根据Type 找到配置的对应的适配器
CallAdapter, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
//如果都没有就抛异常
.......
throw new IllegalArgumentException(builder.toString());
}
public Converter nextResponseBodyConverter(
@Nullable 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 converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter) converter;
}
}
//如果都没有就抛异常
.......
throw new IllegalArgumentException(builder.toString());
}
......
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient(); //创建一个OkHttpClient实例
}
//在后面的分析中,特别要注意platform这个对象,默认实现有android和Java8
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
// Retrofit默认的platform有android 和 java8
// android 创建一个默认的MainThreadExecutor()
// Java8默认为null
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// 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()); //内置了很多默认的数据解析器
converterFactories.addAll(this.converterFactories); //对外默认配置的数据解析器
converterFactories.addAll(platform.defaultConverterFactories()); //24以下,默认为空
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
}
总结来说,HttpServiceMethod初始化的对象在Retrofit对象创建的时候就通过build()默认根据platform的特性实例化了对饮的默认对象。
Retrofit默认实现的适配器(CallAdapter)对象
static class Android extends Platform {
@Override List extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
return Build.VERSION.SDK_INT >= 24
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
}
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
......
@Override
public @Nullable CallAdapter, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
return new CallAdapter>() {
......
@Override public Call adapt(Call call) {
return new ExecutorCallbackCall<>(callbackExecutor, call); //返回一个封装的Call
}
};
}
static final class ExecutorCallbackCall implements Call {
final Executor callbackExecutor;
final Call delegate; //实际上就是传进来的OkHttpCall
// 通过enqueue、execute封装让OkHttpCall发送请求
@Override
public void enqueue(final Callback callback) {
delegate.enqueue(new Callback() {
@Override
public void onResponse(Call call, final Response response) {
callbackExecutor.execute(new Runnable() { //通过MainHandler将结果返回主线程
@Override
public void run() {
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 call, final Throwable t) {
callbackExecutor.execute(new Runnable() { //通过MainHandler将结果返回主线程
@Override
public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
@Override
public Response execute() throws IOException {
return delegate.execute();
}
}
}
Retrofit默认实现的数据解析器(Converter)对象集合
final class BuiltInConverters extends Converter.Factory {
/** Not volatile because we don't mind multiple threads discovering this. */
private boolean checkForKotlinUnit = true;
@Override
public @Nullable Converter responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
if (type == ResponseBody.class) {
//判断注解类型是否是@Streaming
//是,以数据流的形式返回,
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) { //为空类型,返回null
return VoidResponseBodyConverter.INSTANCE;
}
if (checkForKotlinUnit) {
try {
if (type == Unit.class) { //暂时不清楚Unit类型
return UnitResponseBodyConverter.INSTANCE;
}
} catch (NoClassDefFoundError ignored) {
checkForKotlinUnit = false;
}
}
return null; //默认为空
}
@Override
public @Nullable Converter, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,
Annotation[] methodAnnotations, Retrofit retrofit) {
if (RequestBody.class.isAssignableFrom(Utils.getRawType(type))) {
return RequestBodyConverter.INSTANCE;
}
return null;
}
static final class VoidResponseBodyConverter implements Converter {
static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();
@Override
public Void convert(ResponseBody value) {
value.close();
return null;
}
}
static final class UnitResponseBodyConverter implements Converter {
static final UnitResponseBodyConverter INSTANCE = new UnitResponseBodyConverter();
@Override
public Unit convert(ResponseBody value) {
value.close();
return Unit.INSTANCE;
}
}
static final class RequestBodyConverter implements Converter {
static final RequestBodyConverter INSTANCE = new RequestBodyConverter();
@Override
public RequestBody convert(RequestBody value) {
return value;
}
}
static final class StreamingResponseBodyConverter
implements Converter {
static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();
@Override
public ResponseBody convert(ResponseBody value) {
return value;
}
}
static final class BufferingResponseBodyConverter
implements Converter {
static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();
@Override
public ResponseBody convert(ResponseBody value) throws IOException {
try {
// Buffer the entire body to avoid future I/O.
return Utils.buffer(value);
} finally {
value.close();
}
}
}
static final class ToStringConverter implements Converter {
static final ToStringConverter INSTANCE = new ToStringConverter();
@Override
public String convert(Object value) {
return value.toString();
}
}
}
总结来说,Retrofit默认实现一个数据转化器,用来将OkHttp请求的结果通过MainHandler将结果转发到主线程,而默认数据解析器,如果配置了注解@Streaming,则结果返回时,以数据流的形式返回,不然按OkHttp原生解析的形式返回。
后序:这篇文章从源码角度整体分析Retrofit,适配器模式的应用很精妙,在网络封装方面可以很好的借鉴哦。
如果觉得我的文章对你有帮助,请随意赞赏。您的支持将鼓励我继续创作!