retrofit的使用
- 创建描述网络请求的接口
- 创建Retrofit实例
- 创建网络请求接口实例配置网络请求参数
- 发送网络请求
- 处理服务器返回的数据
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
public interface NetService {
@GET("80395694")
Call<ResponseBody> getCall();
}
public class MainActivity{
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://blog.csdn.net/luyuqin0115/article/details/")
.addConverterFactory(GsonConverterFactory.create())
.build();
//创建网络请求接口的实例
NetService service = retrofit.create(NetService.class);
//对 发送请求进行封装
Call<ResponseBody> call = service.getCall();
//发送网络请求(异步)
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.d(TAG, "onResponse: " + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
}
});
}
源码分析
网络请求的本质工作是Okhttp完成,而Retrofit 仅负责网络请求接口的封装。
- 解析网络请求接口的注解配置网络请求参数
- 动态代理 生成网络请求对象
- 网络请求适配器将网络请求对象进行平台适配
- 网络请求执行器发送网络请求
- 数据转换器解析服务器返回数据
- 回调执行器切换线程
- 主线程处理返回结果
创建Retrofit 对象
用build构建者模式创建Retrofit对象
public final class Retrofit {
//存储网络请求相关的配置(网络请求的方法,数据转换器,网络请求适配器,网络请求工厂,url地址等等)
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
//网络请求工厂(默认使用OkHttpCall),成产call请求对象
final okhttp3.Call.Factory callFactory;
//网络请求地址
final HttpUrl baseUrl;
//数据转换器工厂集合 (本质是配置了数据类型转换工厂)
final List<Converter.Factory> converterFactories;
//网络请求适配器工厂的集合(本质是配置了网络请求适配器工厂--默认是ExecutorCallAdapterFactory)
final List<CallAdapter.Factory> callAdapterFactories;
//回调方法执行器 (默认回调方法执行器的作用是切换线程(子线程 到 主线程))
final @Nullable Executor callbackExecutor;
//是否提前对接口当中的注解进行转换
final boolean validateEagerly;
}
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);
}
创建网络请求接口的实例
观察者模式
代理模式
外观模式
public <T> T create(final Class<T> 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);
}
});
}
private void eagerlyValidateMethods(Class<?> service) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method)) {
loadServiceMethod(method);
}
}
}
//给接口中每个方法的注解进行解析,得到ServiceMethod对象。使用单例模式实现ServiceMethod对象的唯一性
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;
}
final class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
//创建一个网络请求适配器,根据网络请求接口方法当中的返回值和注解类型从Retrofit对象中去获取对应的网络请求适配器
CallAdapter<ResponseT, ReturnT> 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<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
//loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
}
异步请求
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
//静态代理的作用,把retrofit的网络请求交给OkhttpCall来做
final Call<T> delegate;
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
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);
}
});
}
});
}
}
class Platform {
static class Android extends Platform {
@IgnoreJRERequirement // Guarded by API check.
@Override boolean isDefaultMethod(Method method) {
if (Build.VERSION.SDK_INT < 24) {
return false;
}
return method.isDefault();
}
//返回默认方法执行器,主要负责在主线程中执行一些回调方法
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
//创建一个默认回调执行器的工厂,用于去生产回调执行器
@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
return Build.VERSION.SDK_INT >= 24
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
@Override int defaultCallAdapterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 2 : 1;
}
@Override List<? extends Converter.Factory> defaultConverterFactories() {
return Build.VERSION.SDK_INT >= 24
? singletonList(OptionalConverterFactory.INSTANCE)
: Collections.<Converter.Factory>emptyList();
}
@Override int defaultConverterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 1 : 0;
}
static class MainThreadExecutor implements Executor {
//获取主线程的Handler
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
//子线程切换到主线程
handler.post(r);
}
}
}
}
Retrofit总结
- Retrofit 将Http请求接口抽象成Java接口
- 在接口中用注解描述和配置网络请求参数
- 用动态代理的方式,动态将网络请求接口的注解解析成HTTP请求
- 用Okhttp来最好执行HTTP请求