HTTP client
来实现网络请求,如okhttp
、httpclient
等RxJava
json
、xml
等Retrofit
比较好的把几个框架的功能组合起来,并没有重复自造轮子,而是高效的把轮子进行组合。其利用OkHTTP
进行网络请求。并且Retrofit
与异步请求框架和类解析框架解耦,使得Retrofit
可以适配多种框架,使用者可以轻松的选择适合自己项目的异步请求和解析的框架。Retrofit
的面向接口的设计方式也是其主要优势,用户通过编写接口,框架替用户实现,用户与框架的依赖只限于接口,网络请求的相关参数等也更清晰。Retrofit
在生成Retrofit
对象和ServiceMethod
对象时候都用到了Builder
模式。通过Builder
来生成类的实例对象更加优雅,尤其在如果类有多个可选的构造参数时,参数较多,初始化时我们可以指定其中的一些而其他的参数如果不指定可以为默认。
Builder
也有缺点:对多生成Builder
对象,增加开销,但总的来说在一些场景下还是利大于弊。
Retrofit
的Converter
和Adapter
都是由抽象工厂模式来生成的。抽象工厂隔离了具体类的生成,系统与产品的创建/组合/表示的过程相独立:Retrofit
的ConverterFactory
和AdapterFactory
都是在Retrofit
对象生成时候制定的,而Converter
和Adapter
都是在Retrofit
代理各个方法时候生成的。
Retrofit
使用了动态代理,用户编写接口,告诉Retrofit
想要什么样的方法,Retrofit
通过动态代理来生成实例对象。用动态代理,完成了从接口到实例对象的过程。与静态代理相比,动态代理一套代码可以同时代理多个原始类/接口。
适配器模式用来将接口A转化成接口B,在Retrofit
中用来将Call
异步接口转化成其他的异步接口。
Retrofit
的设计符合了高内聚,低耦合的原则,有效的将其他框架组织起来,并使其之间解耦,这增强了Retrofit
的易用性和灵活性。Retrofit
合理运用多种设计模式以及其面向接口的编程方式是其达到高内聚低耦合的关键。没有重新造轮子,而是复用其他轮子,让轮子们高效组合到一起也是Retrofi
t的意义。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiService apiService = retrofit.create(ApiService.class);
retrofit2.Call<Student> call = apiService.getStuInfo();
call.enqueue(new retrofit2.Callback<Student>() {
@Override
public void onResponse(retrofit2.Call<Student> call, retrofit2.Response<Student> response) {
//返回数据回调到主线程中处理,这里切换到了主线程进行操作
}
@Override
public void onFailure(retrofit2.Call<Student> call, Throwable t) {
}
});
public interface ApiService {
@GET("https://www.google.com")
Call<Student> getStuInfo();
}
public Builder() {
this(Platform.get());
}
//根据不同运行平台,提供不同的线程池
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
try {
//Class.forName('')
//要求JVM查找并加载指定的类
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
//如果是Android平台,就返回Android对象
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
//支持Java平台
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
//Android平台创建的线程池
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
// 该默认工厂生产的 adapter 会使得Call在异步调用时在指定的 Executor 上执行回调
// 在Retrofit中提供了四种CallAdapterFactory: ExecutorCallAdapterFactory(默认)
、GuavaCallAdapterFactory、Java8CallAdapterFactory、RxJavaCallAdapterFactory
//使用了策略模式
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
//将String类型的url装换成okhttp适用的HttpUrl类型
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
//将url分解成几个碎片
List<String> pathSegments = baseUrl.pathSegments();
//拿到最后一个碎片检测url是不是以“/”结尾
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
baseUrl()
用于配置Retrofit
类的网络请求url
地址,将传入的String
类型url
转化为适合OKhttp
的HttpUrl
类型的url
。
//Converter.Factory抽象工厂模式
//GsonConverterFactory具体工厂
public final class GsonConverterFactory extends Converter.Factory {
public static GsonConverterFactory create() {
return create(new Gson());
}
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
//创建一个含有gson的工厂对象
return new GsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}
public Builder addConverterFactory(Converter.Factory factory) {
//将实例放入到数据转换器工厂类中
//适配器模式
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
public Retrofit build() {
//baseUrl必须要,否则抛异常
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
//如果需要对OkhttpClient进行设置,可以构建OkhttpClient,通过callFactory将构建好的传入,
//如果没有设置,就直接初始化一个OkhttpClient对象
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//用来将回调传递到UI线程
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
//用于存储Call进行转化对象
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
//用于存储转化的数据对象,如果是Gson 就设置返回转化好的gson对象
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
//返回配置好的retrofit对象
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
//进行OkhttpClient设置
public Builder client(OkHttpClient client) {
return callFactory(checkNotNull(client, "client == null"));
}
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}
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 =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
//创建OkhttpCall
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//调用okhttpCall返回rxjava的observer对象或者call对象
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
//首先从serviceMethodCache查询方法是否有缓存,有的话就直接获取,没有就创建一个然后缓存起来
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
public ServiceMethod build() {
//根据请求网络接口的方法返回值的注解类型,从retrofit中获取对应的网络请求适配器类型
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);
}
解析网络请求接口中方法的注解
主要是解析获取Http
请求的方法
注解包括:DELETE、GET、POST、HEAD、PATCH、PUT、OPTIONS、HTTP、retrofit2.http.Headers、Multipart、FormUrlEncoded
处理主要是调用方法 `parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody)
ServiceMethod
中的httpMethod、hasBody、relativeUrl、relativeUrlParamNames
域进行赋值。
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;
}
}
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);
}
类型不能是void否则抛异常
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);
}
}
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = adapterFactories.indexOf(skipPast) + 1;
//遍历CallAdapter.Factory集合,寻找合适工厂,没有提供factory将抛异常
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());
}
//如果最终没有工厂所提供的所需的CallAdapter抛异常
throw new IllegalArgumentException(builder.toString());
}
ExecutorCallAdapterFactory 类中
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
//使用静态代理异步请求
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
// 线程切换,从而在主线程显示结果
// 最后Okhttp的异步请求结果返回到callbackExecutor
// callbackExecutor.execute()通过Handler异步回调将结果传回到主线程进行处理,进行了线程切换
callbackExecutor.execute(new Runnable() {
@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<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
//创建一个默认的回调器,在主线程中回调方法
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
//调用来ExecutorCallAdapterFactory
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
//在主线程中创建handler
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
//获取主线程的handler,在UI线程网络请求回调显示数据
handler.post(r);
}
}
}
**切换线程的流程:
ExecutorCallAdapterFactory
生成了一个ExecutorCallbackCall
对象ExecutorCallbackCall.enqueue(CallBack)
从而调用MainThreadExecutor
的execute()
通过handler
切换到主线程处理返回结果(如显示在Activity
等)**Retrofit
本质上是一个 RESTful
的HTTP
网络请求框架的封装,即通过 大量的设计模式 封装了 OkHttp
,使得简洁易用。具体过程如下:
Retrofit
将 Http
请求 抽象 成 Java
接口HTTP
请求