声明:通过Retrofit的使用步骤来对Retrofit的源码进行解读;
1、基本使用方法:
第一步添加依赖库(app的build.gradle下):
mRetrofit.create(ApiService.class)://创建Api接口,就是将定义好的接口声明传给Retrofit,Retrofit使用代理对ApiService进行解析
1、基本使用方法:
第一步添加依赖库(app的build.gradle下):
dependencies{
implementation 'com.squareup.retrofit2:retrofit:2.3.0'//Retrofit的库
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'//需要使用到的Gson转化库
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'//需要使用的Rxjava库
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'//线程切换的库
}
第二步实际使用:
Retrofit.Builder builder = new Retrofit.Builder();
mRetrofit = builder.baseUrl(AppNetConfig.BASE)
.client(genericClient())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
mRetrofit.create(ApiService.class);
//Retrofit的特殊之处,使用接口对网络请求进行配置,实现解耦功能,这也是这个库流行的根本原因
//接口的声明具体使用方法参考Retrofit的官方介绍
public interface ApiService { //示例
@GET(AppNetConfig.HOME_ENTERPRISE)
Observable<HomeEnterpriseBean> getHomeEnterprise();
}
*genericClient()为产生OkHttpClient的方法,以下仅供参考*
public OkHttpClient genericClient() {
long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MiB
String cacheFile = EnterpriseInfoQuery.mContext.getCacheDir() + "/http";
Cache cache = new Cache(new File(cacheFile), SIZE_OF_CACHE);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
//HttpsUtils采用的张鸿洋的OkHttpUtils中的类
HttpsUtils.SSLParams sslSocketFactory = HttpsUtils.getSslSocketFactory(null, null, null);
return builder.connectTimeout(20000L, TimeUnit.MILLISECONDS)
.readTimeout(20000L, TimeUnit.MILLISECONDS)
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
})
.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
return chain.proceed(chain.request()
.newBuilder()
.addHeader("Authorization", token)
.addHeader("Content-Type", "application/json;charset=-8")
.addHeader("xxx","xxxxxx")//为头部添加自定义字段
.build());
}
})
//添加缓存配合使用,并且需要在头部声明max-age属性
// .addNetworkInterceptor(CachingControlInterceptor.REWRITE_RESPONSE_INTERCEPTOR)
// .addInterceptor(CachingControlInterceptor.REWRITE_RESPONSE_INTERCEPTOR_OFFLINE)
//支持访问Https形式的网址,但是未提供证书校验(与Http仅一个"s"字符的区别,其他没有区别)
.sslSocketFactory(sslSocketFactory.sSLSocketFactory, sslSocketFactory.trustManager)
.cache(cache)
.build();
}
2、步骤分解:
Retrofit.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());//简译:添加转化工厂保证使用responseBody时正常
}
public Builder() {
this(Platform.get());//get()->findPlatform()最终指向为Android平台
}
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) {
}
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();
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);
}
}
}
builder.baseUrl(AppNetConfig.BASE):转入根地址
public Builder baseUrl(String baseUrl) {
//非空检查
checkNotNull(baseUrl, "baseUrl == null");
//将地址转化为HttpUrl的格式
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
.client(genericClient()):初始化OkHttpClient(使用的网络请求是OkHttp3)
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;//*return this;这种写法是Build设计模式的核心
}
.addConverterFactory(GsonConverterFactory.create()):添加转化工厂(可自定义),通用性操作,
包括将发送的字符放到对象里然后通过Gson工厂转为json串(这地方略显繁琐,但是对kotlin而言是方便的)
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()):添加回调,后面会设计同步,异步,很重要的步骤
public static RxJava2CallAdapterFactory create() {
return new RxJava2CallAdapterFactory(null, false);
}
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
if (rawType == Completable.class) {
// Completable is not parameterized (which is what the rest of this method deals with) so it
// can only be created with a single configuration.
return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,
false, true);
}
......
return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
isSingle, isMaybe, false);
}
/*这个get()很重要后面会用到*/
.build():参数检查及设置默认初始化参数
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();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
/*注意:这个类的另外三个方法后面会用到:callAdapter、requestBodyConverter、responseBodyConverter。
这里callAdapter为获取adapterFactoties中添加的实例、其他两个方法类似*/
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
/**
* Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain
* #callAdapterFactories() factories} except {@code skipPast}.
*
* @throws IllegalArgumentException if no call adapter available for {@code type}.
*/
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;
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
......省略异常日志输出
}
上面都是一些前期的参数准备工作,下面开始核心内容:
mRetrofit.create(ApiService.class)://创建Api接口,就是将定义好的接口声明传给Retrofit,Retrofit使用代理对ApiService进行解析
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);//检测是否是接口、是否是单一接口
if (validateEagerly) {//先行检查
eagerlyValidateMethods(service);//--->loadServiceMethod(method);
}
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<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
/*新建OkHttpCall以OkHttp3为基础的网络请求*/
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
/*这个adapter方法最终指向了RxJava2CallAdapter*/
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
--------------------------------------------------
这里的服务方法使用缓存的模式进行加载避免了重复解析,提升了很大的效率。
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;
}
在ServiceMethod中
public ServiceMethod build() {
/*获取callAdapter*/
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
......
/*返回数据转化器*/
responseConverter = createResponseConverter();
/*这个就是对已声明的ApiService注解分析(包括使用的Http(s)协议头部和路径)*/
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
/*解析参数*/
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
......
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
......
return new ServiceMethod<>(this);
}
private CallAdapter<T, R> createCallAdapter() {
......
try {
//noinspection unchecked
/*调用到Retrofit类中的callAdapter(前面有提到RxJava2CallAdapterFactory),最终获取的是RxJava2CallAdapter的实例*/
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);
}
}
private Converter<ResponseBody, T> createResponseConverter() {
Annotation[] annotations = method.getAnnotations();
try {
/*Retrofit中的返回体转化器,指向的是Gson(自定义的则指向自定义)*/
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);
}
}
--------------------------------------------------
在OkHttpCall中的两个重要方法(enqueue异步执行方法,execute同步网络请求方法,核心createRawCall)
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "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;
}
}
}
......
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 Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
......
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
......
return parseResponse(call.execute());
}
private okhttp3.Call createRawCall() throws IOException {
//将参数转化为请求
Request request = serviceMethod.toRequest(args);
//新建OkHttp3为基础的网络请求---->RxJava2CallAdapter中*/
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
-----------------------------------------------------------
RxJava2CallAdapter中的同步异步请求,接入RxJava2的流式编程
@Override public Object adapt(Call<R> call) {
/*并将结果返回为Observable*/
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
......
return observable;
}
CallEnqueueObservable中的核心步骤call.enqueue(callback)
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
CallCallback<T> callback = new CallCallback<>(call, observer);
observer.onSubscribe(callback);
call.enqueue(callback);
}
CallExecuteObservable中核心步骤call.execute()
@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
observer.onSubscribe(new CallDisposable(call));
boolean terminated = false;
try {
Response<T> response = call.execute();
......
}
}
parseResponse方法是很重要的一环,将call返回的Response通过Gson转化为对象
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();
......
try {
T body = serviceMethod.toResponse(catchingBody);
return Response.success(body, rawResponse);
......
}
ServiceMethod中
R toResponse(ResponseBody body) throws IOException {
return responseConverter.convert(body);
}
GsonResponseBodyConverter中有,Retrofit中提到responseBodyConverter的最终指向
@Override public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
return adapter.read(jsonReader);
} finally {
value.close();
}
}
至此真正的网络请求发起并获取对应的response传入Observable中