Retrofit是什么?
简介
Retrofit,中文的翻译为“式样翻新”的意思,是一个基于OKHttp的RESTful网络请求框架。通俗一点来说,Retrofit就是一个网络请求框架的封装。同样是由Square公司开源的Android热门网络框架之一,其具有功能强大、简洁易用及高可拓展性特点。
官网网址:Retrofit官网
Github地址:Github
特点
1、基于OkHttp并遵循Restful API设计风格
2、通过注解的形式,可简便的配置网络请求参数
3、支持同步及异步的网络请求方式
4、支持RxJava
5、支持多种数据格式的解析(Json、XML、Protobuf等)
Retrofit怎么用?
1、gradle引入库
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0' //配置使用Gson解析响应数据 可选
implementation 'com.squareup.retrofit2:adapter-rxjava:2.4.0' //配置支持RxJava 可选
2、初始化Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL) //配置baseUrl
.addConverterFactory(GsonConverterFactory.create()) //配置使用Gson解析响应数据
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) //配置支持RxJava
.build();
网络接口定义
public interface WeatherService {
//使用GET请求 直接返回原始数据
@GET("weather?location=%E5%98%89%E5%85%B4&output=json&ak=5slgyqGDENN7Sy7pw29IUvrZ")
Call<ResponseBody> cityNameQueryWeather();
//使用GET请求 返回Json映射对象
@GET("{weather}?location=%E5%98%89%E5%85%B4&output=json")
Call<WeatherResp> cityWeatherPath(@Path("weather") String weather, @Query("ak") String ak);
//使用POST请求 支持RxJava返回
@FormUrlEncoded()
@POST("{weather}")
rx.Observable<WeatherResp> cityWeatherPost(@Path("weather") String weather, @Field("ak") String ak, @Field("location") String location, @Field("output") String output);
}
同步请求
WeatherService weatherService = retrofit.create(WeatherService.class);
Call<ResponseBody> responseBodyCall = weatherService.cityNameQueryWeather();
try {
Response<ResponseBody> responseBody = responseBodyCall.execute();
System.out.println("call:" + responseBody.body().string());
} catch (IOException e) {
e.printStackTrace();
}
异步请求
WeatherService weatherService = retrofit.create(WeatherService.class);
Call<WeatherResp> responseBodyCall = weatherService.cityWeatherPath("weather", "5slgyqGDENN7Sy7pw29IUvrZ");
responseBodyCall.enqueue(new Callback<WeatherResp>() {
@Override
public void onResponse(Call<WeatherResp> call, Response<WeatherResp> response) {
System.out.println("call:" + response.toString());
}
@Override
public void onFailure(Call<WeatherResp> call, Throwable t) {
}
});
RxJava支持
WeatherService weatherService = retrofit.create(WeatherService.class);
weatherService.rxCityWeatherPost("weather", "5slgyqGDENN7Sy7pw29IUvrZ", "%E5%98%89%E5%85%B4", "json")
.subscribeOn(Schedulers.io()) //在新线程里面处理网络请求
.observeOn(AndroidSchedulers.mainThread()) //在主线程里面接受返回的数据
.subscribe(new rx.Observer<WeatherResp>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(WeatherResp weatherResp) {
System.out.println("call:" + weatherResp.toString());
}
});
详细的Retrofit的注解配置及各注解的使用,推荐参考
这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)
Retrofit核心执行流程是怎样?
关键类功能说明
类 | 功能说明 |
---|---|
Retrofit | 里面包含了很多对象,serviceMethodCache(自定义的接口映射对象集合)、baseUrl(请求地址)、callFactory(默认为OKHttpCall)、converterFactories(数据解析器工厂集合)、callAdapterFactories(Call适配器工厂集合)、callbackExecutor(回调执行,Android平台默认为MainThreadExecutor)使用Builder模型构建 |
Platform | Retrofit中用来管理多平台的方法,支持Android、Java8。通过findPlatform获取对应的平台,同时也初始化了defaultCallAdapterFactory工厂 |
ServiceMethod | 接口映射的网络请求对象,通过动态代理,将自定义接口的标注转换为该对象,将标注及参数生成OkHttp所需的Request对象。Retrofit的create通过动态代理拦截,将每一个自定义接口转换成为一个ServiceMethod对象,并通过通过serviceMethodCache进行缓存。 |
Call<T> | Retrofit定义的网络请求接口,包含execute、enqueue等方法 |
OkHttpCall | Ohttp的Call实现,通过createRawCall得到真正的 okhttp3.Call对象,用于进行实际的网络请求 |
CallAdapter.Factory | CallAdapter的静态工厂,包含get的抽象方法,用于生产CallAdapter对象 |
ExecutorCallAdapterFactory | Android平台默认的CallAdapter工厂,get方法使用匿名内部类实现CallAdapter,返回ExecutorCallbackCall,实现了Call |
ExecutorCallbackCall | 采用静态代理设计,delegate实际为OkHttpCall,使用callbackExecutor实现回调在主线程中执行 |
RxJavaCallAdapterFactory | Rxjava平台的CallAdapter工厂,get方法返回RxJavaCallAdapter对象 |
RxJavaCallAdapter | Rxjava平台的设配器,返回observable对象 |
Converter.Factory | 数据解析器工厂,用于生产Converter实例 |
GsonConverterFactory | 数据解析工厂实例,返回了GsonResponseBodyConverter数据解析器 |
GsonResponseBodyConverter | Gson的数据解析器,将服务端返回的json对象转换成对应的java模型 |
Response<T> | Retrofit网络请求响应的Response |
代码执行流程
- 通过Build模式构建Retrofit对象
- 自定义的接口interface,包含接口方法及相关标注
- 执行定义的接口方法
- 通过Proxy.newProxyInstance进行动态代理拦截
- 通过反射将定义的标注方法解析生成ServiceMethod对象(表示一个网络请求的封装对象)并加入serviceMethodCache队列中,避免重复解析
- 创建OkHttpCall对象, 继承了Call<T>接口,桥接okhttp3.Call rawCall
- 从Retrofit对象的callAdapterFactories工厂集合获取CallAdapter,并调用adapt方法。如果是默认的使用ExecutorCallAdapterFactory设配返回Call<Object>,如果设置了RxJavaCallAdapterFactory,返回observable。
- 获取适配器转换后的对象,执行同步请求或者异步请求。
- 创建Okhttp的RealCall对象
- 通过反射的arg参数,调用serviceMethod.toCall(),构建生成Okhttp的RealCall所需要的Request对象
- 通过OkHttp的RealCall执行对应的同步或异步请求
- 请求成功,通过parseResponse解析请求参数
- 通过数据转换器responseConverter.convert(body),将原始数据转换为对象
- 回调解析完的数据对象Respone(T)
Retrofit 如何将定义的interface转换成网络请求?
我们都知道,Retrofit通过自定义interface及相关的标注来描述一个http的请求,使用非常简便,且易于维护。
这是Retrofit设计的精髓之一,,当调用Retrofit的create()方法时,会进行动态代理监听。当执行具体的接口方法时,会回调InvocationHandler。通过反射解析method的标注及参数,生成ServiceMethod对象,ServiceMethod中封装了OKHttp网络请求所需的相关参数。
源码实现如下:
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, @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<Object, Object> serviceMethod =o
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
通过源码我们知道,具体的转换方法为 (ServiceMethod<Object, Object>) loadServiceMethod(method),具体的实现如下:
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
通过Builder构建模式,创建一个ServiceMethod对象,并加入缓存,具体的构造实现如下:
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
public ServiceMethod build() {
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?");
}
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);
}
build()方法会通过反射去解析method的标注、参数的类型等。详细的解析可参考源码ParameterHandler相关实现,这里主要对流程进行剖析。
总结一下,Retrofit通过自定义interface及相关的标注来描述一个http的请求,当调用Retrofit的create()方法时,会进行动态代理监听。当执行具体的接口方法时,会回调InvocationHandler。通过反射解析method的标注及参数,生成ServiceMethod对象,ServiceMethod中封装了OKHttp网络请求所需的相关参数。这就是Retrofit将定义的interface转换成网络请求对象的过程。
Retrofit的Converter机制是如何实现?
Converter种类
Retrofit支持多种数据解析方式,使用时需要在Gradle添加依赖。
数据解析器 | Gradle依赖 |
---|---|
Gson | com.squareup.retrofit2:converter-gson:2.4.0 |
Jackson | com.squareup.retrofit2:converter-jackson:2.4.0 |
Simple XML | com.squareup.retrofit2:converter-simplexml:2.4.0 |
Protobuf | com.squareup.retrofit2:converter-protobuf:2.4.0 |
Moshi | com.squareup.retrofit2:converter-moshi:2.4.0 |
Wire | com.squareup.retrofit2:converter-wire:2.4.0 |
Scalars | com.squareup.retrofit2:converter-scalars:2.4.0 |
Converter实现流程
添加Converter工厂
首先在Retrofit的初始化添加Converter,addConverterFactory(GsonConverterFactory.create())。具体实现如下:
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
将Converter的工厂加入到converterFactories集合中。
触发数据转换
通过上述的流程分析,我们知道Retrofit当网络请求成功后会执行,OkHttpCall中的parseResponse方法。
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
// Remove the body's source (the only stateful object) so we can pass the response along.
rawResponse = rawResponse.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
if (code < 200 || code >= 300) {
try {
// Buffer the entire body to avoid future I/O.
ResponseBody bufferedBody = Utils.buffer(rawBody);
return Response.error(bufferedBody, rawResponse);
} finally {
rawBody.close();
}
}
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}
其中关键的代码为 T body = serviceMethod.toResponse(catchingBody),具体实现如下:
/** Builds a method return value from an HTTP response body. */
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
数据转换器的创建
这里就是 Converter实现转换的地方,那么responseConverter在哪里进行初始化呢?在ServiceMethod的Build方法中,会调用createResponseConverter()进行数据解析器的创建,实现如下:
private Converter<ResponseBody, T> 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);
}
}
调用了 retrofit.responseBodyConverter方法
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
调用了 retrofit.nextResponseBodyConverter方法
public <T> Converter<ResponseBody, T> 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<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());
}
通过Retrofit的converterFactories工厂集合匹配获取开始添加的数据转换工厂
默认的数据转换工厂
通过Retrofit build() 中发现如下代码,converterFactories.add(new BuiltInConverters()),可知Retrofit默认的数据转换器工厂为BuiltInConverters。主要实现如下:
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
return Utils.isAnnotationPresent(annotations, Streaming.class)
? StreamingResponseBodyConverter.INSTANCE
: BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
会将数据转换为ResponseBody对象,所以如果Retrofit默认不使用任何数据解析器,定义interface方法时接收数据对象使用 Call<ResponseBody>。
Retrofit的CallAdapter机制是如何实现?
Retrofit支持多种网络请求适配器方式:guava、Java8和rxjava 。Android默认的适配器工厂为ExecutorCallAdapterFactory,最后的回调通过ExecutorCallbackCall切换至主线程运行。
CallAdapter种类
网络请求适配器 | Gradle依赖 |
---|---|
guava | com.squareup.retrofit2:adapter-guava:2.4.0 |
Java8 | com.squareup.retrofit2:adapter-java8:2.4.0 |
rxjava | com.squareup.retrofit2:adapter-rxjava:2.4.0 |
CallAdapter实现流程
添加CallAdapter工厂
首先在Retrofit的初始化添加CallAdapter工厂,addCallAdapterFactory(RxJavaCallAdapterFactory.create())。具体实现如下:
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
将CallAdapter的工厂加入到callAdapterFactories集合中。
CallAdapter的adapt实现
通过上述Retrofit的create方法中分析可知,当拦截到interface的方法调用后最后会执行 return serviceMethod.adapt(okHttpCall)。adapt的实现如下:
T adapt(Call<R> call) {
return callAdapter.adapt(call);
}
就是在这个地方触发了callAdapter的adapt方法。返回最终适配的具体对象。
默认的CallAdapter工厂
Android平台默认的CallAdapter工厂为ExecutorCallAdapterFactory。通过Retrofit的build()方法可知:
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
platform.defaultCallAdapterFactory的实现如下:
CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor != null) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
return DefaultCallAdapterFactory.INSTANCE;
}
ExecutorCallAdapterFactory的CallAdapter创建如下:
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
} else {
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
public Type responseType() {
return responseType;
}
public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallAdapterFactory.ExecutorCallbackCall(ExecutorCallAdapterFactory.this.callbackExecutor, call);
}
};
}
}
adapt方法最后返回还是Call<Object>对象,具体的适配实现由ExecutorCallbackCall执行,具体源码如下:
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;
}
public void enqueue(final Callback<T> callback) {
Utils.checkNotNull(callback, "callback == null");
this.delegate.enqueue(new Callback<T>() {
public void onResponse(Call<T> call, final Response<T> response) {
ExecutorCallbackCall.this.callbackExecutor.execute(new Runnable() {
public void run() {
if (ExecutorCallbackCall.this.delegate.isCanceled()) {
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
public void onFailure(Call<T> call, final Throwable t) {
ExecutorCallbackCall.this.callbackExecutor.execute(new Runnable() {
public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
public Response<T> execute() throws IOException {
return this.delegate.execute();
}
}
具体的执行还是通过delegate(OkHttpCall)来执行,但是在回调使用了 ExecutorCallbackCall.this.callbackExecutor.execute()方法,Android平台的callbackExecutor实现为MainThreadExecutor。具体源码如下:
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
所以ExecutorCallAdapterFactory中适配最后的设配对象还是Call<Object>,实现还是OkHttpCall,通过 MainThreadExecutor,将回调切换在UI线程中运行
CallAdapter的创建
在ServiceMethod的Build方法中,createCallAdapter()进行适配器的的创建,实现如下:
private CallAdapter<T, R> 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.");
}
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
return (CallAdapter<T, R>) 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);
}
}
调用了 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) {
checkNotNull(returnType, "returnType == null");
checkNotNull(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());
}
通过Retrofit的callAdapterFactories工厂集合匹配获取开始添加的适配器工厂
如何自定义一个Converter及CallAdapter?
自定义Converter
1、需要定义一个工厂类继承Converter.Factory
2、复写responseBodyConverter及requestBodyConverter方法
3、在Retrofit定义时加入自定义的Converter,addConverterFactory(new CustomConverterFactory())
/**
* @author allen
* @date 2018/8/7
* 返回服务端返回的string结果
*/
public class CustomConverterFactory extends Converter.Factory {
@Nullable
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return StringResponseBodyConverter.INSTANCE;
}
@Nullable
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return StringRequestBodyConverter.INSTANCE;
}
static final class StringResponseBodyConverter implements Converter<ResponseBody, String> {
static final CustomConverterFactory.StringResponseBodyConverter INSTANCE = new CustomConverterFactory.StringResponseBodyConverter();
@Override
public String convert(ResponseBody value) {
try {
System.out.println("CustomConverterFactory");
return value.string();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
}
static final class StringRequestBodyConverter implements Converter<RequestBody, RequestBody> {
static final CustomConverterFactory.StringRequestBodyConverter INSTANCE = new CustomConverterFactory.StringRequestBodyConverter();
@Override
public RequestBody convert(@NonNull RequestBody value) {
return value;
}
}
}
自定义CallAdapter
1、需要定义一个工厂类继承CallAdapter.Factory
2、复写CallAdapter<?, ?> get方法
3、在Retrofit定义时加入自定义的CallAdapter, addCallAdapterFactory(new CustomCallAdapterFactory())
/**
* @author allen
* @date 2018/8/7
*/
public class CustomCallAdapterFactory extends CallAdapter.Factory {
@Nullable
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
return new CallAdapter<Object, Object>() {
@Override
public Type responseType() {
return String.class;
}
@Override
public Object adapt(Call<Object> call) {
System.out.println("CustomCallAdapterFactory adapt(");
return call;
}
};
}
}
Retrofit中运用了那些设计模式?
1、建造者模式
Retrofit对象的创建、ServiceMethod对象创建都使用Build模式,将复杂对象的创建和表示分离,调用者不需要知道复杂的创建过程,使用Build的相关方法进行配置创建对象。
2、外观模式
Retrofit对外提供了统一的调度,屏蔽了内部的实现,使得使用该网络库简单便捷。
3、动态代理模式
通过动态代理的方式,当调用Retrofit的create()方法时,会进行动态代理监听。当执行具体的接口方法时,会回调InvocationHandler。通过反射解析method的标注及参数,生成ServiceMethod对象。
4、静态代理模式
Android平台默认的适配器ExecutorCallbackCall,采用静态代理的模式。具体的实现delegate为OkHttpCall。
5、工厂模式
Converter及CallAdapter的创建都采用了工厂模式进行创建。
6、适配器模式
CallAdapter的adapt采用了适配器模式,使得interface的返回对象可以动态扩展,增强了灵活性
总结
思考
大多数流行的开源框架都是经过顶级coder的设计,包含了很多精妙的设计。多学习分析,收益良多。
参考资料
这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)
Android:手把手带你深入剖析 Retrofit 2.0 源码
推荐
关于
欢迎关注我的个人公众号
微信搜索:一码一浮生,或者搜索公众号ID:life2code