源码地址: https://github.com/square/retrofit
可以看出Retrofit是使用idea,maven依赖编写的Java工程,并不是一个Android 工程。
Retrofit的简单使用:
1、创建Service接口
public interface HistoryDataService {
@GET("japi/toh?v=1.0&month=10&day=1&key=956c0df840307c89f68271325ccc8454")
Call getResult();
}
2、创建 Call
retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())//gson自动解析
.baseUrl(NetworkConstant.JUHE_URL)//主机地址
.build();
HistoryDataService historyDataService = retrofit.create(HistoryDataService.class);
Call call = historyDataService.getResult();
3、使用Call执行网络请求
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
Retrofit源码解析:
1、Retrofit 的创建过程
Retrofit是通过建造者模式构建出来的,看一些细节
//Retrofit.java
public Builder() {
this(Platform.get());
}
看一下Platform的get方法
//Platform .java
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {//根据不同的平台获取不同的线程池
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("org.robovm.apple.foundation.NSObject");
return new IOS();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
......
}
Platform 的get 方法最终调用了findPlatform方法,根据不同的平台获取不同的线程池。
看一下Android 的线程池:
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
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);//使用Handler将 Runnable 转发到UI线程
}
}
}
其实就是个回调接口,使用Handler将 Runnable 转发到UI线程。
查看Build方法:
public Retrofit build() {
if (baseUrl == null) { //baseurl不能为空,否则抛异常
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) { //如果没有手动设置callFactory,则直接new OkHttpClient, 用于后续网络请求
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) { //如果没有手动设置callbackExecutor,则获取平台默认的callbackExecutor,用于将Runable转发到UI线程,AndroidPlatform 默认使用Handler.post(Runable)
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
// 添加calladapter 用于后期子线程到主线程的回调
List callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters. //存储转化对象,例子中调用addConverterFactory(GsonConverterFactory.create()) ,设置返回的数据转化为Gosn可以解析的对象
List converterFactories = new ArrayList<>( //converterFactories可以设置多个,retrofit会自动选择使用哪个converterFactoriy 解析数据
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());
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
}
2、Call 的创建过程
HistoryDataService historyDataService = retrofit.create(HistoryDataService.class);
public T create(final Class 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();
//proxy 被代理的对象,method 被代理的方法,args方法参数
@Override public Object invoke(Object proxy, Method method, 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);//如果是method是object的,则可以直接调用
}
if (platform.isDefaultMethod(method)) {//java8中接口引入默认方法,如果是接口的默认方法,直接调用
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod serviceMethod = loadServiceMethod(method); //这个method是 HistoryDataService 的getResult()方法
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall); //这里创建ExeExecutorCallbackCall
}
});
}
loadServiceMethod方法:
private final Map serviceMethodCache = new LinkedHashMap<>();
ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) { //主要起一个缓存作用,如果存在method对应的ServiceMethod ,直接返回,如果不存在的话,创建并存入
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
查看 ServiceMethod.Builder(this, method).build();
public ServiceMethod build() {
callAdapter = createCallAdapter();//获取retrofit创建时callAdapter
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();//从retrofit创建时的responseConverter中,遍历,获取一个合适的Convert用来转换对象
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);
}
ExecutorCallbackCall部分代码如下所示:
static final class ExecutorCallbackCall implements Call {
final Executor callbackExecutor;
final Call delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback callback) {
if (callback == null) throw new NullPointerException("callback == null");
delegate.enqueue(new Callback() {
@Override public void onResponse(Call call, final Response response) {
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 call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
其实是将 call 封装为 ExecutorCallbackCall ,前面用到了适配器模式。
通过ExecutorCallbackCall 将请求结果回调到主线程。
3、Call 的 enqueue方法
@Override public void enqueue(final Callback callback) {
call.enqueue(new okhttp3.Callback() {//实际上调用的是okhttp3 Call 类型的call 的enqueue方法
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response response;
try {
response = parseResponse(rawResponse);//解析response
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}
}
查看parseResponse 方法:
Response 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) {
return Response.success(null, rawResponse);
}
ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
try {
T body = serviceMethod.toResponse(catchingBody);// 将 catchingBody 转为body
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;
}
}
看一下 serviceMethod的toResponse方法:
/** Builds a method return value from an HTTP response body. */
T toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);//这块将body转换为json,
}
在之前的例子中,使用的是GsonConvertFactory ,查看一下GsonConvertFactory 的代码
@Override
public Converter responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter); //创建 GsonResponseBodyConverter
}
查看GsonResponseBodyConverter 源码:
final class GsonResponseBodyConverter implements Converter {
private final Gson gson;
private final TypeAdapter adapter;
GsonResponseBodyConverter(Gson gson, TypeAdapter adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
return adapter.read(jsonReader);
} finally {
value.close();
}
}
}
在 GsonResponseBodyConverter 的 convert 方法里将回调的数据转为Json格式,。
call的enqueue方法主要做的事是用Okhttp来请求网络,并将返回的Response进行数据转换回调给UI线程。