Retrofit是一款java平臺的http client工具墩虹,常用于Android砌们。主要基于OkHttp做應(yīng)用層封裝,把http域名轉(zhuǎn)換成java方法,可以自動轉(zhuǎn)換json結(jié)果為javabean寞宫。github鏈接,官方教程
Retrofit turns your HTTP API into a Java interface.
簡單使用流程介紹:
- 先構(gòu)建okhttpclient
- Builder模式構(gòu)建Retrofit
- 編寫interface捧灰,通過注解寫域名淆九,把http請求轉(zhuǎn)化為java方法
- Retrofit#createService創(chuàng)建實例,返回一個Call
- call.enqueue(callback)
- callback接收java bean結(jié)果
構(gòu)建OkHttpClient
- 配置cache
- 配置攔截器
主要就是上面的配置
構(gòu)建Retrofit
Builder
- callFactory(okhttp3.Call.Factory) 傳入一個call毛俏,默認(rèn)是Okhttpclient
interface Factory {
Call newCall(Request request);
}
- baseurl 傳入基準(zhǔn)域名
- addConvertFactory 序列化工廠
public interface Converter<F, T> {
T convert(F value) throws IOException;
/** Creates {@link Converter} instances based on a type and target usage. */
abstract class Factory {
//ResponseBody converter的工廠炭庙,這個converter負(fù)責(zé)ReponseBody和bean的轉(zhuǎn)換
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
//RequestBody converter的工廠,這個converter用于RequestBody和bean的轉(zhuǎn)換煌寇,一般是@Body焕蹄,@Part,@PartMap
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
//負(fù)責(zé)string和bean的轉(zhuǎn)換阀溶,一般是@Field腻脏,@Header鸦泳,@Path,@Query以及它們對應(yīng)的map注解
public Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
}
}
converterFactory需要顯式指定永品,使用fastjson或者gson對應(yīng)的converter即可做鹰,具體可參考Retrofit的wiki
- addCallAdapterFactory 主要是將Retrofit的Call<T>轉(zhuǎn)為其他方式,如RxJava鼎姐,默認(rèn)是ExecutorCallAdapterFactory
public interface CallAdapter<R, T> {
Type responseType();
T adapt(Call<R> call);
abstract class Factory {
public abstract CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit);
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
//Call如何在Observable運行
protected void subscribeActual(Observer<? super Response<T>> observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call<T> call = originalCall.clone();
CallDisposable disposable = new CallDisposable(call);
observer.onSubscribe(disposable);
if (disposable.isDisposed()) {
return;
}
boolean terminated = false;
try {
Response<T> response = call.execute();
if (!disposable.isDisposed()) {
observer.onNext(response);
}
if (!disposable.isDisposed()) {
terminated = true;
observer.onComplete();
}
} catch (Throwable t) {
Exceptions.throwIfFatal(t);
if (terminated) {
RxJavaPlugins.onError(t);
} else if (!disposable.isDisposed()) {
try {
observer.onError(t);
} catch (Throwable inner) {
Exceptions.throwIfFatal(inner);
RxJavaPlugins.onError(new CompositeException(t, inner));
}
}
}
}
- callbackExecutor 傳入一個Executor钾麸,用于回調(diào)執(zhí)行
創(chuàng)建請求interface
- http方法注解,用于標(biāo)識請求的方法 GET炕桨,POST饭尝,PUT,DELETE献宫,HEAD钥平,OPTIONS,PATCH姊途,
- 域名替換注解涉瘾,在url用{}包含,Path吭净,Query睡汹,QueryMap
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
- 表單和multipart ,F(xiàn)ormUrlEncoded寂殉,F(xiàn)ield,Multipart原在,Part
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
- Header友扰,Body
createService
public <T> T create(final Class<T> 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);
}
});
}
- Retrofit的所有工作都是為了createService這一步,通過動態(tài)代理返回一個實例庶柿,通過RequestFactory解析注解構(gòu)建Request村怪。Call,Callback浮庐,Response都有一層封裝來隔離甚负。調(diào)用callFactory,傳入Request返回Call审残,調(diào)用Call返回Response梭域,然后通過Converter來逆序列化body為entity
- 解析方法注解和參數(shù)注解,ServiceMethod搅轿,RequestFactory
- HttpServiceMethod#createCallAdapter病涨,#createResponseConverter,通過Retrofit里的factory創(chuàng)建對應(yīng)的實例
- HttpServiceMethod#invoke返回結(jié)果璧坟。
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
- OkHttpCall負(fù)責(zé)構(gòu)建Call
- 最終調(diào)的是DefaultCallAdapterFactory#ExecutorCallbackCall既穆,默認(rèn)把Call轉(zhuǎn)化并代理赎懦,目前其實只干了一件事,因為OkHttp默認(rèn)在非UI線程回調(diào)callback幻工,ExecutorCallbackCall在UI線程分發(fā)
call#enqueue(callback)
public interface Callback<T> {
void onResponse(Call<T> call, Response<T> response);
void onFailure(Call<T> call, Throwable t);
}