Retrofit2源码解析(一)
一、适用人群。会使用Retrofit,想更好更全面的了解Retrofit的童鞋。
二、解析
1、获取Retrofit实例
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
成员变量解释
1)callFactory 处理网络请求的工厂类,依赖于okhttp3.Factory
2)baseUrl 网络请求的基础地址
3)converterFactories 实例类转化工厂
4)adapterFactories CallAdapter生成工厂
5)callbackExecutor 回调的执行者,一个executor
6)validateEagerly 是否提前验证methods是实现自接口
这里着重说下converterFactories 和adapterFactories 的区别和作用
在Rxjava中,网络请求的接口一般是这种形式
public interface HttpLogin {
@POST("account/login")
XXX<YYY> login(@Body ZZZ body);
}
converterFactories 是负责文字和实体类互相转化,需要把http返回的body转成yyy实体类,以及把ZZZ实体转成字符串。
adapterFactories 是负责生成XXX实体类的适配器。在DefaultCallAdapterFactory.java文件中可以看出陆默认的仅支持XXX为retrofit2.Call类型
看下默认赋值
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
可以看出:
1) 必须设置baseUrl
2)默认使用okhttp3.OkHttpClient使用网络请求工厂
3)callbackExecutor回调执行器用的是MainThreadExecutor,简单的说就是在主线程回调
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
4)adapterFactories默认添加了retrofit2.DefaultCallAdapterFactory
DefaultCallAdapterFactory.class
*/
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
static final CallAdapter.Factory INSTANCE = new DefaultCallAdapterFactory();
@Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
//可以看出支持的返回类型仅为retrofit2.Call,其他类型就不支持了
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public <R> Call<R> adapt(Call<R> call) {
return call;
}
};
}
}
5)converterFactories默认是个retrofit2.BuiltInConverters
retrofit2.BuiltInConverters代码太多,就只贴出关键的
//可以看出只支持入参为ResponseBody类型
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (type == ResponseBody.class) {
if (Utils.isAnnotationPresent(annotations, Streaming.class)) {
return StreamingResponseBodyConverter.INSTANCE;
}
return BufferingResponseBodyConverter.INSTANCE;
}
if (type == Void.class) {
return VoidResponseBodyConverter.INSTANCE;
}
return null;
}
6)validateEagerly默认flase;
2、根据上面的要求创建一个请求接口
public interface HttpLogin {
@POST("account/login")
retrofit2.Call<ResponseBody> login(@Body RequestBody body);
}
1) retrofit2.Call login = retrofit.create(HttpLogin.class)
.login(RequestBody.create(MediaType.parse(“Application/json”), “{\”account\”:112333}”));
这里看下Retrofit.create(final Class service) 函数
public <T> T create(final Class<T> service) {
//验证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, Object... args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
//如果该方法在的类.class是Object.class
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//如果是平台的默认方法,在Android Platform恒为false。
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//将方法存缓存,然后取。。。就这样
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
这里出现了ServiceMethod,发现对它不了解的话就无法进行下去了。我们来看看
ServiceMethod类
public ServiceMethod.Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
//方法的注解集
this.methodAnnotations = method.getAnnotations();
//方法的参数类型集
this.parameterTypes = method.getGenericParameterTypes();
//方法的参数注解集(@path.etc)
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);
}
//解析接口的入参与入参注解
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);
}
}
return new ServiceMethod<>(this);
}
ServiceMethod(Builder<T> builder) {
//返回的类型的工厂类
this.callFactory = builder.retrofit.callFactory();
//请求的适配器
this.callAdapter = builder.callAdapter;
this.baseUrl = builder.retrofit.baseUrl();
//返回类型的转成实体类的转化器
this.responseConverter = builder.responseConverter;
this.httpMethod = builder.httpMethod;
//请求的实际路径。
this.relativeUrl = builder.relativeUrl;
this.headers = builder.headers;
this.contentType = builder.contentType;
this.hasBody = builder.hasBody;
this.isFormEncoded = builder.isFormEncoded;
this.isMultipart = builder.isMultipart;
this.parameterHandlers = builder.parameterHandlers;
}
这时候得到了retrofit2.Call login对象,这个call很像Okhttp里的Call;
这时候调用
login.enqueue(new retrofit2.Callback<ResponseBody>() {
@Override
public void onResponse(retrofit2.Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
System.out.println("onResponse ");
try {
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(retrofit2.Call<ResponseBody> call, Throwable t) {
System.out.println("onFailure " + t.getMessage());
}
});
实际上调用了retrofit2.OkHttpCall<T>. enqueue(final Callback<T> callback)方法
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("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();
} catch (Throwable t) {
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
//这里是调用了okhttp.call的方法
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callSuccess(Response<T> response) {
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
执行完。控件台打印出
onResponse
{"code":999999,"des":"参数错误[密码不能为空]"}
Process finished with exit code 0