Retrofit官网
Retrofit的使用如下
1.Retrofit引用--在build.gradle中增加引用
implementation 'com.squareup.retrofit2:retrofit:2.5.0' //Retrofit
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'//返回值转化成json
2.定义接口
public interface GitHubService {
@GET("users/{user}/repos")
Call> listRepos(@Path("user") String user);
}
3.请求
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/") //必须以"/"结尾,不然将抛出异常
.addConverterFactory(GsonConverterFactory.create())
.build();
GitHubService netApi = retrofit.create(GitHubService.class);
Call> responseCall = netApi.listRepos("octocat");
responseCall.enqueue(new Callback>() {
@Override
public void onResponse(Call> call, Response> response) {
Log.e(TAG, "onResponse: =" + response.code());
}
@Override
public void onFailure(Call> call, Throwable t) {
Log.e(TAG, "onFailure: =" + t.toString());
}
});
4.结果返回值
onResponse: =200
按照源码跟读如下:
查看responseCall.enqueue(Callback)方法,得知接口Call的方法,再向上追溯到netApi.listRepos("octocat"),属于接口调用方法返回Call值,再向上追溯retrofit.create(GitHubService.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();
private final Object[] emptyArgs = new Object[0];
@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);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
代码核心功能是:
- 动态代理,调用接口方法时,就是调用new InvocationHandler()对象里的invoke的方法 ,核心就是调用loadServiceMethod(method).invoke(args != null ? args : emptyArgs)
到这里查看Retrofit代码使用,分两部分,一部分是通过Build模式生成Retrofit对象,一部分是使用Retrofit内的create方法,即使用动态代理处理接口的方法
首先我们从通过Build模式建立Retrofit对象开始查看源代码,直接查看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 callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List converterFactories = new ArrayList<>(
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);
}
- 对baseUrl判断是否为null
- callFactory变量对应的是okhttp3.call.Factory类型,默认初始化的实现是okhttp3的OkHttpClient对象
- callbackExecutor变量对象的是java.util.concurrent.Executor类型,默认初始化的实现是platform.defaultCallbackExecutor();其中platform通过Build()构造函数知道是在retrofit2.Platform类里实现的是Android内部类,而其中defaultCallbackExecutor()方法返回的是MainThreadExecutor类得知,是通过handler切换线程到主线程
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();
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
- callAdapterFactories变量对应的的是retrofit2.CallAdapter.Factory,该变量用来适配网络请求,例如适配RxJava2CallAdapterFactory
- converterFactories 变量对应的是retrofit2.Converter.Factory,该变量用来适配数据转换,例如适配GsonConverterFactory.create(),其中会有默认的数据解析器 converterFactories.add(new BuiltInConverters());
查看Retrofit类的create(final Class service)方法内的loadServiceMethod(method).invoke(args != null ? args : emptyArgs)
private final Map> serviceMethodCache = new ConcurrentHashMap<>();
ServiceMethod> loadServiceMethod(Method method) {
ServiceMethod> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
- ConcurrentHashMap是HashMap的一个线程安全的,用来缓存ServiceMethod;根据Method判断是否有缓存,有则直接取出来;否则通过ServiceMethod.parseAnnotations(this, method)重新创建,并缓存起来
abstract class ServiceMethod {
static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract T invoke(Object[] args);
}
- RequestFactory.parseAnnotations(retrofit, method)返回的RequestFactory类是注解相关的数据
final class RequestFactory {
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
private final Method method; //方法
private final HttpUrl baseUrl; //基地址
final String httpMethod; //请求方法,即get post delete
private final @Nullable String relativeUrl; //方法的相对地址,即path部分
private final @Nullable Headers headers; // 注解的header内容,请求头
private final @Nullable MediaType contentType; //请求体
private final boolean hasBody; //是否有请求体
private final boolean isFormEncoded; //是否是表单
private final boolean isMultipart; //是否图片类
private final ParameterHandler>[] parameterHandlers;//方法参数处理器
- Retrofit不是网络请求框架,是封装的Okhttp的请求框架,通过注解拿到请求参数封装后由okhttp3请求,所以该类是解析各种注解,获取到请求的各种方法;requestFactory是注解的相关参数
- HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)方法确定HttpServiceMethod类是ServiceMethod的实现类,包括Invoke方法
static HttpServiceMethod parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
CallAdapter callAdapter = createCallAdapter(retrofit, method);
Type responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
Converter responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
- 构建函数HttpServiceMethod对象的四个变量requestFactory是注解对应的方法及参数,callFactory是Retrofit里对应的OkHttpClient对象
- callAdapter的创建代码如下:
private static CallAdapter createCallAdapter(
Retrofit retrofit, Method method) {
Type returnType = method.getGenericReturnType();
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
return (CallAdapter) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create call adapter for %s", returnType);
}
}
- 首先从网络请求接口方法中获取注释,然后根据注释和注释返回类型,接着调用retrofit.callAdapter()方法从retrofit中获取适配器。咱们跟着代码会发发现其实最后调用的是retrofit的nextCallAdapter()
public CallAdapter, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
...
}
- 在for循环中,根据请求参数在网络适配工厂中创建网络适配器并返回该适配器
- responseConverter变量的创建代码如下:
private static Converter createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create converter for %s", responseType);
}
}
最终还是到Retrofit类中nextResponseBodyConverter方法
public Converter nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter) converter;
}
}
...
}
- 可以看到,和创建网络请求适配器一样的创建方法,根据响应类型和请求方法注释数值,从数据转换器工厂中创建数据转换器并返回
至此loadServiceMethod(method)已完成,创建并返回ServiceMethod的实现类HttpServiceMethod,做的内容包括:解析网络请求接口参数、网络请求适配器、response数据解析器等工作
- 查看HttpServiceMethod的invoke方法
创建OkHttpCall对象new OkHttpCall<>(requestFactory, args, callFactory, responseConverter)
由于retrofit的网络请求是由okhttp3请求,所以OkHttpCall就是对okhttp的call对象的封装,OkHttpCall对象的同步及异步代码如下:
//网络请求异步操作方法
@Override
public void enqueue(final Callback 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) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
//网络请求同步操作方法
@Override public Response execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else if (creationFailure instanceof RuntimeException) {
throw (RuntimeException) creationFailure;
} else {
throw (Error) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException | Error e) {
throwIfFatal(e); // Do not assign a fatal error to creationFailure.
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());
}
- 不管是同步还是异步,都创建了okhttp3.call rawCall变量,最终调用都是rawCall的同步或者异步方法,也就是okhttp3.Call的enqueue()和execute()
callAdapter.adapt(okHttpCall)
这个方法很显然使用适配器模式,将某些咱们需要处理的事件,适配成其他平台可以使用的类型,并在该平台使用。这里调用serviceMethod的adapt适配方法,传入了上面步骤7中创建的OkHttpCall实例,并将适配对象返回;比如可以使用RxJava2CallAdapterFactory.create()来创建了一个RxJava2CallAdapter的适配器来适配RxJava2平台,适配成RxJava2平台能使用的Call
咱们接下来看Retrofit的CallAdapter接口中的Rxjava2CallAdapter实现类的adapter()方法:
package retrofit2.adapter.rxjava2;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Observable;
import io.reactivex.Scheduler;
import java.lang.reflect.Type;
import javax.annotation.Nullable;
import retrofit2.Call;
import retrofit2.CallAdapter;
import retrofit2.Response;
final class RxJava2CallAdapter implements CallAdapter {
private final Type responseType;
@Override public Object adapt(Call call) {
Observable> 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;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
return observable.singleOrError();
}
if (isMaybe) {
return observable.singleElement();
}
if (isCompletable) {
return observable.ignoreElements();
}
return observable;
}
}
- 该适配方法返回了一个Observable被观察者对象