Retrofit uses the tutorial address http://square.github.io/retrofit/source
version
com.squareup.retrofit2:retrofit:2.5.0
Sometimes looking at the source code, I seem to understand but not understand. It's really confusing, so this time I read and debug directly the source code. See retrofit is the execution process.
- The first step is to create a Retrofit object, configure some parameters in Retrofit through the creator mode (see the source code for specific parameters), and then perform an example.
- The second step is to call the method through the Retrofit instance object
create(ApiService.class)
. This method parsesApiService
the methods, annotations, and parameters in the interface class through the proxy mode. In its process and byloadServiceMethod(method)
caching its methods, annotations, and parameters intoprivate final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
it. When loading for the second time, it is directly taken out of the cache and a network loading request is made. - In the third step, the request is loaded successfully, and operations are performed on the data returned by the background.
Through the builder mode, generate a Retrofit instance
/**
* 创建Retrofit 实例,并针对参数进行配置
* 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 callFactory = this.callFactory;
if (callFactory == null) {
//实例OkhttpClient对象
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
//默认配置返回参数适配器,例如,返回RxJava2CallAdapterFactory
// 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));
//默认配置返回的数据类型,比如GSON(GsonConverterFactory),XML,
// 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());
//通过建造者模式,返回Retrofit实例
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
Request the network by calling the create() method
public <T> T create(final Class<T> service) {
//判断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);
}
});
}
As can be seen from the above, through the proxy mode, the methods , parameters , and annotations ApiService.class
in it are parsed through this method.method
emptyArgs
loadServiceMethod(method)
ServiceMethod<?> loadServiceMethod(Method method) {
//获取serviceMethodCache的缓存
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
//根据method获取网络请求实例
result = serviceMethodCache.get(method);
//如果缓存是空的
if (result == null) {
//则解析method
result = ServiceMethod.parseAnnotations(this, method);
//解析完成后,存入serviceMethodCache,
serviceMethodCache.put(method, result);
}
}
//返回网络请求实例
return result;
}
First read the network request instance method
from the cache serviceMethodCache
, and return its instance object directly if it is not empty.
Otherwise, through ServiceMethod.parseAnnotations(this, method)
parsing, result
store its instance object in the cache serviceMethodCache
after completion
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//主要的在这里,parseAnnotations
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);
}
It can be seen from the above that through RequestFactory.parseAnnotations(retrofit, method);
this method, retrofit is performed, and the method is parsed to generate RequestFactory
an object, and the object is passed into it HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
for parsing to generate ServiceMethod
a network request object.
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
//创建适配器,RxJava
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
//获取callAdapter响应类型
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.");
}
//创建数据类型转换器,比如Gson,
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
//将其OkHttpClient对象 赋值给 callFactory
okhttp3.Call.Factory callFactory = retrofit.callFactory;
//将其解析完成的参数对象,传入HttpServiceMethod构造方法当中进行实例,并返回
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
Pass retrofit,method,
the two instance parameters, pass createCallAdapter(retrofit, method);
the parse, and return callAdapter
the instance object. After the adapter conversion and parsing is completed, the instance object createResponseConverter(retrofit, method, responseType);
is returned through parsing responseConverter
. Finally return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
the instance object.
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method) {
//获取方法返回的数据类型模型
Type returnType = method.getGenericReturnType();
//获取方法注解
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
//通过retrofit对象callAdapter方法进行解析,完事后返回适配器实例对象
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);
}
}
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
It can be seen that method.getGenericReturnType()
the data type model and method.getAnnotations();
annotation array are passed into the retrofit.callAdapter(returnType, annotations)
method for analysis, and the adapter type of the method is returned.
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
.....
//获取callAdapterFactories列表的索引,
int start = callAdapterFactories.indexOf(skipPast) + 1;
//针对列表进行循环查找,实例 CallAdapter适配器,返回该实例对象
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
省略以下代码
.....
throw new IllegalArgumentException(builder.toString());
}
For callAdapterFactories
the location of the obtained list, find callAdapterFactories.get(i).get(returnType, annotations, this);
the object through the for loop, and return the generated object
private static <ResponseT> Converter<ResponseBody, ResponseT> 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);
}
}
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
省略部分代码
...
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
省略部分代码
...
throw new IllegalArgumentException(builder.toString());
}
For converterFactories
the location of the obtained list, find converterFactories.get(i).get(returnType, annotations, this);
the object through the for loop, and return the generated object
private HttpServiceMethod(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
CallAdapter<ResponseT, ReturnT> callAdapter,
Converter<ResponseBody, ResponseT> responseConverter) {
this.requestFactory = requestFactory;
this.callFactory = callFactory;
this.callAdapter = callAdapter;
this.responseConverter = responseConverter;
}
This is the last step, instantiating new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
the object. In fact, it is a network request instance object ServiceMethod<T>
.
//调用传入网络方法请求参数
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
All the above parameters OkHttpCall
are requested through networking, and the data returned by the background is analyzed and called back.
1. Network request interface class,
interface ApiService {
@GET("/article/list/{page}/json")
fun getListArticleData(@Path("page") page: Int): Call<BaseData<ArticleData>>
@GET("/project/list/{page}/json")
fun getListData(@Path("page") page: Int, @Query("cid") cid: Int): Call<BaseData<ArticleData>>
}
2. General interface address class Note: The interface address provided by Hongyang Dashen
is used , and you can test it yourself
object ApiUrl {
val BASE_URL = "http://www.wanandroid.com"
var ARTICLE_LIST = "/article/list/{page}/json"
}
3. How to use
//配置
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
1.实例 Retrofit对象
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(ApiUrl.BASE_URL)
.build()
2.通过代理方法创建api接口类
val apiService = retrofit.create(ApiService::class.java)
3.调用接口内部的方法
val listArticleData = apiService.getListArticleData(1)
4.通过接口方法返回的实例进行回调,操作后台返回的数据
listArticleData.enqueue(object : Callback<BaseData<ArticleData>> {
//联网失败或数据解析失败
override fun onFailure(call: Call<BaseData<ArticleData>>, t: Throwable) {
println("t = $t")
}
//联网成功,后台返回数据
override fun onResponse(call: Call<BaseData<ArticleData>>, response: Response<BaseData<ArticleData>>) {
val mutableList: MutableList<ArticleData> = response.body()!!.data!!.datas as MutableList<ArticleData>
}
})
Let's end first.
To sum up, I have done two days of source code research. When you look with your heart, there will always be gains.