Android-retrofit源码解析
目录
一,前言
二,使用
三,源码分析
一,前言
retrofit是目前比较流行的网络框架,但它本身并没有网络请求的功能,网络请求的功能是由okhttp来完成的。retrofit只是负责网络请求接口的封装,让我们更加方便的请求网络。
在对retrofit框架进行了解之前,我们需要先了解okhttp,另外retrofit涉及到的设计模式很多,我们主要要了解动态代理模式和适配器模式。
Android-okhttp详解-CSDN博客
Java 代理模式之静态代理与动态代理_java静态代理模式-CSDN博客
Android设计模式--适配器模式_android 适配器模式-CSDN博客
二,使用
在build.gradle配置引用:
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
创建数据类:
data class ArticleBean (
val chapterName :String,
val link :String
)
创建请求接口:
interface YzTestService {
@GET("article/list/0/{name}")
fun yzTest(@Path("name") name:String?): Call<List<ArticleBean>>
}
在activity使用:
class CommonActivity : AppCompatActivity() {
var url = "https://www.wanandroid.com"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_common)
val retrofit =Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build()
val service =retrofit.create(YzTestService::class.java)
val repos:Call<List<ArticleBean>> = service.yzTest("json")
repos.enqueue(object :Callback<List<ArticleBean>>{
override fun onResponse(call: Call<List<ArticleBean>>, response: Response<List<ArticleBean>>) {
Log.d("yz","请求成功:"+response.body().toString())
}
override fun onFailure(call: Call<List<ArticleBean>>, t: Throwable) {
Log.d("yz","请求失败:"+t.toString())
}
})
}
}
三,源码分析
分析源码一般是从使用入手,一般是着眼于最核心的代码。
从使用分析,我们先看repos.enqueue它的源码:
void enqueue(Callback<T> callback);
结果是个抽象方法,所以我们继续往上看它的使用service.yzTest("json"),这个是我们自己创建的,然后接着往上看retrofit.create(YzTestService::class.java)的源码:
public <T> T create(final Class<T> service) {
//判断是否接口 不是接口抛出异常
validateServiceInterface(service);
return (T)
//动态代理模式
Proxy.newProxyInstance(
//第一个参数 任意的类加载器
service.getClassLoader(),
//第二个参数 传入的service的class对象
new Class<?>[] {service},
//第三个参数 静态内部类
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
//最主要的方法
@Override
public @Nullable 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);
}
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
// 经过一系列判断 符合条件 走这里
: loadServiceMethod(method).invoke(args);
}
});
}
然后就来看看loadServiceMethod(method)这个方法:
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;
}
接着继续看ServiceMethod.parseAnnotations(this, method)这个方法:
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//获取方法的注解信息等 创建请求工厂 里面包含请求的url,请求方式,请求参数等等
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);
}
如果符合判断条件,则走HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)
看看这个类:
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT>
它继承了ServiceMethod这个类,我们在看loadServiceMethod(method).invoke(args)的invoke的方法时,发现它是ServiceMethod的抽象方法,然后我们又看到了HttpServiceMethod这个类继承了ServiceMethod,所以我们在HttpServiceMethod这个类里面找一下invoke这个方法,它就是ServiceMethod的具体实现:
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
然后看它的adapt方法:
protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
它是HttpServiceMethod的一个抽象方法,所以我们只能倒回去看 OkHttpCall这个类:
final class OkHttpCall<T> implements Call<T>
发现它是继承了Call,就是上面我们说的:
void enqueue(Callback<T> callback);
这个抽象方法。
所以我们看看OkHttpCall这个类里面enqueue这个方法的具体实现:
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(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 {
//创建okhttp3的Call
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<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
@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) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}
上面的代码都很简单,主要就是创建了一个okhttp3的Call,并用这个Call对象去请求网络
创建对象的代码为:
call = rawCall = createRawCall();
还有一个主要方法就是:
response = parseResponse(rawResponse);
这行代码主要就是解析返回的数据。具体代码比较简单,就是数据的具体解析。这里就不做具体分析了。
最重要的方法就是:
callback.onResponse(OkHttpCall.this, response);
callback.onFailure(OkHttpCall.this, e);
这两个回调就是我们使用的回调。这样整个流程就通了。
看完主线之后,再来看看上面没有看的HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)这个方法:
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;
Annotation[] annotations = method.getAnnotations();
Type adapterType;
//判断是否支持kotlin挂起方法
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType =
Utils.getParameterLowerBound(
0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response<T>.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
} else {
// TODO figure out if type is nullable or not
// Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
// Find the entry for method
// Determine if return type is nullable or not
}
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
adapterType = method.getGenericReturnType();
}
// 关键代码 创建CallAdapter
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
if (responseType == okhttp3.Response.class) {
throw methodError(
method,
"'"
+ getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (responseType == Response.class) {
throw methodError(method, "Response must include generic type (e.g., Response<String>)");
}
// TODO support Unit for Kotlin?
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;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForResponse<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForBody<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}
从上面的代码中我们提取出一个关键代码:createCallAdapter,来看看它的源码:
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
try {
//noinspection unchecked
return (CallAdapter<ResponseT, ReturnT>) 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:
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?, ?> nextCallAdapter(
@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
Objects.requireNonNull(returnType, "returnType == null");
Objects.requireNonNull(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;
}
}
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(callAdapterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
这里面没有什么有用的代码 关键就是callAdapterFactories.get(i).get(returnType, annotations, this);这个方法,我们先看下callAdapterFactories是什么:
final List<CallAdapter.Factory> callAdapterFactories;
再看下它在哪里赋值的:
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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> 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);
}
这个就是在我们使用的时候,调用Retrofit.build方法的时候,赋值的。
具体看下它的赋值内容:
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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
因为我们是android平台 所以我们直接查看platform.defaultCallbackExecutor()找android平台就能看到它的具体实现:
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
这个就是切换到了主线程。
然后我们回到上面看看callAdapterFactories.get(i).get(returnType, annotations, this);的方法:
@Override
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException(
"Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
}
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
final Executor executor =
Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
? null
: callbackExecutor;
return new CallAdapter<Object, Call<?>>() {
@Override
public Type responseType() {
return responseType;
}
@Override
public Call<Object> adapt(Call<Object> call) {
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}
};
}
然后我们就发现了adapt方法,我们回到前面的代码:
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
这个里面的adapt就是上面的adapt,它把OKHttpcall又包了一层,具体看看怎么包装的:
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;//传入的android平台的executor 用于切换主线程
final Call<T> delegate; //OKHttpCall
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
delegate.enqueue(
new Callback<T>() {
@Override
public void onResponse(Call<T> call, final Response<T> response) {
//请求完成之后 切换到主线程
callbackExecutor.execute(
() -> {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on
// cancellation.
//调用者传入的callback
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
//调用者传入的callback
callback.onResponse(ExecutorCallbackCall.this, response);
}
});
}
@Override
public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(() -> 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();
}
@Override
public Timeout timeout() {
return delegate.timeout();
}
}
这样就在内部结果返回时自动切换到了主线程,避免了用户自己切换线程的麻烦。