知其所以然
源码分析首先从入口开始,先来回忆Retrofit的使用步骤:
Retrofit流程1.创建Retrofit实例
2.创建 网络请求接口实例 并 配置网络请求参数
3.发送网络请求
4.解析网络请求完成服务器返回的数据
创建Retrofit实例
1,Builder设置参数
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
Retrofit实例是通过建造者模式Builder类进行创建的,Builder类包含以下可以设置参数的方法:
/**
* 可提前通过OkHttpClient 设置基本参数类似baseUrl、各种拦截器等
*/
public Builder client(OkHttpClient client) {
return callFactory(checkNotNull(client, "client == null"));
}
/**
* 网络请求器的工厂
* 作用:生产网络请求器(Call)
* 如果没有设置Retrofit是默认使用OkHttpClient
*/
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}
/**
* Set the API base URL.
*
* @see #baseUrl(HttpUrl)
*/
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
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");
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
/**
* 数据转换器工厂的集合
* 作用:放置数据转换器工厂
* 数据转换器工厂作用:生产数据转换器(converter)
*/
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
/**
* 网络请求适配器工厂的集合
* 作用:放置网络请求适配器工厂
* 网络请求适配器工厂作用:生产网络请求适配器(CallAdapter)
* 如果没有设置默认使 ExecutorCallAdapterFactory
* 后面在细说
*/
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
adapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
/**
* 方法回调器,可以控制结果返回的线程等
* 注意: {@code executor} 不是用作 {@linkplain #addCallAdapterFactory 方法的返回类型
*/
public Builder callbackExecutor(Executor executor) {
this.callbackExecutor = checkNotNull(executor, "executor == null");
return this;
}
/**
* Retrofit调用 {@link #create}时 , 设置成true这个配置可以提前对业务接口中的注解进行验证转换的标志
*位
*/
public Builder validateEagerly(boolean validateEagerly) {
this.validateEagerly = validateEagerly;
return this;
}
这里我们细讲下baseUrl,其他的后面调用的时候在做分析:Baseurl
baseUrl的设置还是有点讲究的,我们一般设置一个String类型的字符串,Retrofit会把String转换成符合OKHttp请求的HttpUrl,最好按规矩办事,不然容易出问题:
1,baseUrl应该以"/"结尾(非强制,但这样设置能避免很多问题)
2,方法设置的url只如果以“/”开头,默认就是绝对值,同样也可以设置一个完整的Url
baseUrl不以“/”结尾
正解: http://example.com/api/ + foo/bar/ = http://example.com/api/foo/bar/
错误: http://example.com/api + foo/bar/ = http://example.com/foo/bar/;
HttpUrl会通过各种手段BaseUrl截取最后一个“/”之前的内容作为BaseUrl
方法设置的url只如果以“/”开头
BaseUrlL: http://example.com/api/
方法设置的url: /foo/bar/
最终请求的完整url:http://example.com/foo/bar/
BaseUrl: http://example.com/
方法设置的url:/foo/bar/
最终请求的完整url:http://example.com/foo/bar/
如果方法设置的url以“/”开头则被认为是绝对值,最终的而结果是截取掉BaseUrl第一个“/”后面的部分在进行拼接
方法设置的url如果是个完成的url,baseUrl将不起作用
BaseUrl: http://example.com/
方法设置的url:https://github.com/square/retrofit/
最终请求的完整url:https://github.com/square/retrofit/
BaseUrl: http://example.com/
方法设置的url://github.com/square/retrofit/
最终请求的完整url:http://github.com/square/retrofit/(注意是http开头)
2,参数设置完成开始build方法
build方法的源码部分
build方法会在一些参数没有配置的情况下会创建一个默认的对象
/**
* Create the {@link Retrofit} instance using the configured values.
* <p>
* Note: If neither {@link #client} nor {@link #callFactory} is called a default {@link
* OkHttpClient} will be created and used.
*/
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//如果没有自定义okhttp3.Call.Factory则默认使用OkHttpClient,OkHttp请求的关键类
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//回调方法执行,处理结果回调线程等,通过platform.defaultCallbackExecutor()默认拿到的是MainThreadExecutor
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 创建防御类型的对象(避免对同一个对象的操作),如果没有设置则默认为ExecutorCallAdapterFactory,如果使用rxjava则需要设置RxJavaCallAdapterFactory
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);
}
在创建执行方法回调callbackExecutor 时用到 platform.defaultCallbackExecutor(),platform是Builder的构造方法里面创建的一个平台对象
Builder(Platform platform) {
this.platform = platform;
// 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());
}
public Builder() {
this(Platform.get());
}
我们一般使用的时候不会去设置platform,因为默认的就是Android平台
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
//通过findPlatform去寻找默认的平台
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
//android开发这里是默认的平台
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");
//IOS都支持?
return new IOS();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
//这里是android平台的实现
static class Android extends Platform {
//platform.defaultCallbackExecutor()调用,默认是MainThreadExecutor,这是一个将结果发送到主线程的回调方法执行器,也可以通过自定义处理
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
//如果没有设置对rxjava(RxJavaCallAdapterFactory)的支持这里 默认ExecutorCallAdapterFactory是对Call对象的处理
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
//通过Looper.getMainLooper()拿到主线程的looper将结果发送到主线程
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
Retrofit还可以在其他的平台使用
平台包括:Android、Rxjava、Guava和java8,需要添加对应的RxJavaCallAdapterFactory,Java8
CallAdapterFactory等
2.配置网络请求参数
Retrofit实例创建之后会调用create方法创建interface对象,在通过接口对象调用相应的方法
public interface CategoryService {
@GET("top250")
Call<MovieEntity> getcategoryList(@Query("start") int start, @Query("count") int count);
@POST("/form")
@FormUrlEncoded
Call<ResponseBody> submit(@Field("username") String name, @Field("token") String token);
}
retrofit.create(CategoryService.class).getcategoryList(0,10);
create方法
create源码部分
public <T> T create(final Class<T> service) {
//检查是否为接口
Utils.validateServiceInterface(service);
//如果设置了validateEagerly为true,就会带调用eagerlyValidateMethods对接口中的所有方法进行提前配置
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
//这里还是拿到平台对象,和实例一样用Android平台的对象
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, Object... args)
throws Throwable {
// 如果是来自Object的方法则按调默认的invoke方法
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//platform.isDefaultMethod 默认返回false,Android没有重写,固为false,java8倒是有重写这个方法
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//这里就是loadServiceMethod配置ServiceMethod
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
//通过创建的serviceMethod对象里创建的CallAdapter的adapt方法去适配生成相应的网络请求代理 (Call,Obsevalble)
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
//拿到接口中的所有方法进行配置
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {
loadServiceMethod(method);
}
}
}
ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
//将参数配置给ServiceMethod
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
create创建相应的接口对象后调用getcategoryList方法会通过InvocationHandler 配置ServiceMethod对象,并通过CallAdapter的adpt方法生成相应的Call或Observable。
这里主要涉及到ServiceMethod的配置问题需要详细说明
1,Retrofit的参数传递给ServiceMethod
2,方法的注解和方法参数的注解解析并复制给ServiceMethod的参数
so,ServiceMethod包含了网络请求的所有参数成了全村人的希望
关于ServiceMethod
public 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对象最后会调用他的adapt方法创建Call或ObserVable
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);
}
//请求方法不能为空,比如GET,POST必须有一个
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
//如果注解是@GET则@Multipart和@FormEncoded都不能存在
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);
}
//没有设置url(在方法注解和参数注解都没有设置url)
if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
//@Body注解的必须同时存在@Multipart或@FormEncoded或POST放等其中一种
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
//@FormEncoded注解至少要一个参数注解是@Field
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
//@Multipart注解至少要一个参数注解是@Part
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}
return new ServiceMethod<>(this);
}
关于CallAdapter
ServiceMethod对象生成以后会利用CallAdapter的adapter方法生成Call对象,典型的适配器模式
CallAdapter的生成在ServiceMethod中
private CallAdapter<?> createCallAdapter() {
Type returnType = method.getGenericReturnType();
//方法的返回类型中泛型不能是T,K等变量或者通配符
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 {
return 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(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
拿到第一个null后的值,如果集合中没有null则start 为0
int start = adapterFactories.indexOf(skipPast) + 1;
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());
}
throw new IllegalArgumentException(builder.toString());
}
adapterFactories默认是ExecutorCallAdapterFactory,他的get方法
通过get方法生成CallAdapter
@Override
public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Call<?>>() {
@Override public Type responseType() {
return responseType;
}
//最后通过adapt方法创建Call<R> 的实现类ExecutorCallbackCall
@Override public <R> Call<R> adapt(Call<R> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
创建的CallAdapter调用adapt方法创建了Call的ExecutorCallbackCall实现类
3.发送网络请求并处理结果
Call call = retrofit.create(CategoryService.class).getcategoryList(0,10);
call.enqueue(new Callback<MovieEntity>() {
@Override
public void onResponse(Call<MovieEntity> call, Response<MovieEntity> response) {
resultTV.setText(response.body().toString());
}
@Override
public void onFailure(Call<MovieEntity> call, Throwable t) {
resultTV.setText(t.getMessage());
}
});
这里的call实际是Call的实现类ExecutorCallbackCall,ExecutorCallbackCall的源码
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
//这里参数传进来的是MainThreadExecutor,和OkHttpCall对象
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
//当调用enqueue方法时
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
代理类OkHttpCall调用enqueue
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> 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<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
@Override public boolean isExecuted() {
return delegate.isExecuted();
}
@Override public Response<T> execute() throws IOException {
return delegate.execute();
}
@Override public void cancel() {
delegate.cancel();
}
@Override public boolean isCanceled() {
return delegate.isCanceled();
}
@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
@Override public Call<T> clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override public Request request() {
return delegate.request();
}
}
代理模式一层套一层
关于OkHttpCall 的enqueue方法源码
@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 {
//关键部分创建okhttp3.Call
call = rawCall = createRawCall();
} catch (Throwable 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)
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();
}
}
});
}
createRawCall是关键的创建 okhttp3.Call对象的方法
private okhttp3.Call createRawCall() throws IOException {
//把serviceMethod中所有的参数都赋值给Request,毕竟 Request才是OkHttp想要的
Request request = serviceMethod.toRequest(args);
//这里serviceMethod.callFactory是oKHttpClient,后面newCall就是OkHttp创建okhttp3.Call 的方法了
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
网友评论