舉例說明:
請求一個api: https://api.github.com/repos/{owner}/{repo}/contributors
查看github上某個repo的contributors.
首先你要這樣建一個接口:
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(@Path("owner")String owner,@Path("repo")String repo);
}
然後創建一個Retrofitpublic static final String BASIC_URL="https://api.github.com";
Retrofit mRetrofit =new Retrofit.Builder().baseUrl(BASIC_URL).addConverterFactory
(GsonConverterFactory.create()).build();
創建一個GitHubGitHub gitHub =mRetrofit.create(GitHub.class);
Call<List<Contributor>> call =gitHub.contributors("owner","repo");
最後回調獲取數據call.enqueue(new Callback<List<Contributor>>(){
@Override
public void onResponse(Response<List<Contributor>>respone){
for(Contributor controbutor: respone.body){
}
}
@Override
public void onFailure(Throwable t){
}
});
create方法重要就是返回了一個動態代理對象。(Java動態代理就是Java開發給了開發人員一種可能:當你要調用某個類的方法前,插入你想要執行的代碼
比如你要執行某個操作前,你必須要判斷這個用戶是否登錄,或者你在付款前,你需要判斷這個人的賬戶中存在這麼多錢。這麼簡單的一句話,我相信可以把一個不懂技術的人也講明白Java動態代理是什麼東西了。)
GitHub github = retrofit.create(GitHub.class);
源碼: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();
@Override public Object invoke(Object proxy, Method method, 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 loadMethodHandler(method).invoke(args);
}
});
生成一個HTTP請求就是這句:Call<List<Contributor>> call = github.contributors("square", "retrofit");
github是一個動態代理對象,並不是一個真正的Githb接口的implements對象,當github對象調用contributors方法時
,Retrofit其實是執行了動態代理的InvocationHandler對象,最後會創建一個MethodHandler對象(Github接口翻譯成一個HTTP請求,也就是MethodHandler對象),
這個對象中包含了4部分內容
static MethodHandler<?> create(Retrofit retrofit, Method method) {
CallAdapter<Object> callAdapter = (CallAdapter<Object>) createCallAdapter(method, retrofit);
Type responseType = callAdapter.responseType();
Converter<ResponseBody, Object> responseConverter =
(Converter<ResponseBody, Object>) createResponseConverter(method, retrofit, responseType);
RequestFactory requestFactory = RequestFactoryParser.parse(method, responseType, retrofit);
return new MethodHandler<>(retrofit.client(), requestFactory, callAdapter, responseConverter);
}
1. OkHttpClient:Retrofit默認生成的,發送網絡請求的工具2. RequestFactory: 類似於Volley中的Request,包含了HTTP請求的Url、Header信息,MediaType、Method以及RequestAction數組,通過RequestFactoryParser.parse(method, responseType, retrofit)生成,主要作用就是解析整個Http請求的所有數據,得到整個Http請求全部的信息,通過@Path和@Query註解拼接Url
3. CallAdapter:HTTP請求返回數據的類型
private static CallAdapter<?> createCallAdapter(Method method, Retrofit retrofit) {
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw Utils.methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw Utils.methodError(method, "Service methods cannot return void.");
}
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw Utils.methodError(e, method, "Unable to create call adapter for %s", returnType);
}
}
4. Converter:數據轉換器,HTTP返回的數據解析成Java對象private static Converter<ResponseBody, ?> createResponseConverter(Method method,
Retrofit retrofit, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw Utils.methodError(e, method, "Unable to create converter for %s", responseType);
}
}
創建這4個對象的目的就是爲了執行下面這句代碼
Object invoke(Object... args) {
return callAdapter.adapt(new OkHttpCall<>(client, requestFactory, responseConverter, args));
}
這個也就是github.contributors("square", "retrofit")返回的Call對象最後你調用Call對象的execute()或enqueue(Callback<T> callback)方法,就能發送一個Http請求了
Retrofit接口
1.這個接口就是retrofit請求數據返回的接口,只有兩個方法
void onResponse(Response<T> response);
void onFailure(Throwable t);
2.Converter<F, T>
這個接口主要的作用就是將HTTP返回的數據解析成Java對象,主要由Xml、Gson、protobuf等等,你可以在創建Retrofit對象時添加你需要使用的Converter實現(看上面創建Retrofit對象的代碼)
3.Call<T>
這個接口主要的作用就是發送一個HTTP請求,Retrofit默認的實現是OkHttpCall<T>,你可以根據實際情況實現你自己的Call類,這個設計和Volley的HttpStack接口設計的思想非常相似,子類可以實現基於HttpClient或HttpUrlConnetction的HTTP請求工具,這種設計非常的插件化,而且靈活
4.CallAdapter<T>
上面說到過,CallAdapter中屬性只有responseType一個,還有一個<R> T adapt(Call<R> call)方法,這個接口的實現類也只有一個,DefaultCallAdapter。這個方法的主要作用就是將Call對象轉換成另一個對象,可能是爲了支持RxJava才設計這個類的吧。
===========================================》