相信大家都用過Retrofit這個框架,但是面試官讓你說說retrofit這個框架往往面試者不知道怎麼回答,在這裏我給大家提供一個思路。
1、基本的使用。
第一步、通過Retrofit的builder模式創建一個retrofit對象,可以在builder裏面設置okhttpclient、baseurl、callAdapterFactroy、addConverterFactory等信息。
第二步、通過得到的retrofit對象加工要請求的接口,得到一個接口對象。
第三步、通過這個接口對象,調用接口裏面的方法得到一個網絡工作對象。
第四步、通過這個網絡工作對象調用enqueue方法或者execute方法發起請求並且回調回請求的結果。具體代碼如下:
//1、通過builder方式創建一個retrofit對象,可以添加client baseurl addConverterFactory addCallAdapterFactory 等信息
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("")
.addConverterFactory(null)
.addCallAdapterFactory(null)
.client(null)
.build();
//2、通過retrofit.create加工得到一個網絡接口對象
INetApiService iNetApiService = retrofit.create(INetApiService.class);
//3、調用網絡接口對象的接口函數,得到一個網絡工作對象
Call<Book> call = iNetApiService.getBook();
//4、通過網絡工作對象發起一個請求並回調回請求的結果
call.enqueue(new Callback<Book>() {
@Override
public void onResponse(Call<Book> call, Response<Book> response) {
}
@Override
public void onFailure(Call<Book> call, Throwable t) {
}
});
從上面的用法就可以看到,retrofit的存在不是它去請求對象,它的作用是生成幫助開發者生成網絡請求對象的封裝,和按照接口返回對應的網絡工作對象,真正的網絡請求發生在網絡工作對象上的。
retrofit解決的問題:在以前做網絡請求的時候,會考慮到如何封裝請求數據,如何發起請求,到最後對返回數據的封裝分類都需要開發人員自己維護,開發成本大不說,還容易出錯。而retrofit通過簡單的配置就可以實現上面複雜的過程。所以要想拆分retrofit就要主要分爲三個方面來,請求數據的封裝,請求對象生成及其如何發起網絡請求的,最後對請求數據的封裝。任何網絡問題都逃不過這三部分。
1、請求數據(請求行、請求頭、請求體)的封裝。
2、生成請求對象發起請求。
3、響應數據的封裝(響應行、響應頭、響應體)。
2、retrofit的如何定製擴展。
擴展主要分爲三個方面
第一方面、用誰來生成網絡工作對象,在retrofit中雖然只能傳入一個OkhttpClient對象,但是okhttp有豐富的擴展性,可以定製自己的攔截器,可以實現數據的緩存等。
第二方面、生成的網絡工作對象進行轉換(我們實際進行請求的是okhttp3裏面的realCall,而在網絡接口中定義的Call對象是在retrofit2中定義的,所以需要一個適配器進行轉換),retrofit裏面添加rxJava支持,可以返回一個Observable對象。
第三方面、對網絡返回的數據進行解析,可以添加自己的數據解析器,定義自己的convertor類和ConvertorFactory類。
3、retrofit原理分析。
ServiceMethod 算是對請求數據的整體封裝
動態代理首先會爲每一方法生成一個ServiceMethod對象,存入緩存中,這個對象包含來網絡請求所用到的一切,請求方法、請求的連接、請求頭、callAdapter的適配器、convertor等信息。
如何找到合適的CallAdapter?
根據返回值找到對應的CallAdapter,如果是ExecuteCallAdapterFactory則返回的callAdapter對象爲CallAdapter,如果是Rxjava則返回的是Rxjava2CallAdapter對象
1、獲取當前方法的返回類型method.getGenericReturnType()。
2、遍歷添加的CallAdapterFactory數組,通過每一個factory的get方法裏面確認是否能創建該類型的對象,ExecutorCallAdapterFactory 代碼如下
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
如何來確認responseConvertor對象呢?
通過泛型的返回值來進行選定的。Gson選定代碼如下
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
再來看一下如何生成對象請求對象的併發出請求的
創建一個retrofit2 包下的OkhttpCall對象。這個call對象裏面有兩個引用一個是ServiceMath對象一個是okhttp3包下的Call對象。
最後看一下返回的serviceMath.callAdapter.adapt(okhttpcall)方法
會生成一個ExecuteCallbackCall對象(默認的CallAdapterFactory),通過這個對象調用enqueue方法會調用retrofit2裏面okhttpCall對象的enqueue方法,最終對調用okhttp3包下call 對象的enqueue方法。
數據轉換
在retrofit2包下的okhttpCall對象,enqueue方法會對okhttp包下Call返回的數據進行解析,解析類是servicemath對象的reaponseConvertor對象,然後將解析好的數據返回回來。
4、以及閱讀retrofit源碼的感受。
分析網絡框架可以從大的方面去着手,主要分爲三步。
1、如何創建請求數據。
2、如何創建請求對象和發起請求。
3、如何對請求數據的處理。