Retrofit是一款java平台的http client工具,常用于Android。主要基于OkHttp做应用层封装,把http域名转换成java方法,可以自动转换json结果为javabean。github链接,官方教程
Retrofit turns your HTTP API into a Java interface.
简单使用流程介绍:
- 先构建okhttpclient
- Builder模式构建Retrofit
- 编写interface,通过注解写域名,把http请求转化为java方法
- Retrofit#createService创建实例,返回一个Call
- call.enqueue(callback)
- callback接收java bean结果
构建OkHttpClient
- 配置cache
- 配置拦截器
主要就是上面的配置
构建Retrofit
Builder
- callFactory(okhttp3.Call.Factory) 传入一个call,默认是Okhttpclient
interface Factory {
Call newCall(Request request);
}
- baseurl 传入基准域名
- 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负责ReponseBody和bean的转换
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
//RequestBody converter的工厂,这个converter用于RequestBody和bean的转换,一般是@Body,@Part,@PartMap
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
//负责string和bean的转换,一般是@Field,@Header,@Path,@Query以及它们对应的map注解
public Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
}
}
converterFactory需要显式指定,使用fastjson或者gson对应的converter即可,具体可参考Retrofit的wiki
- addCallAdapterFactory 主要是将Retrofit的Call<T>转为其他方式,如RxJava,默认是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,用于回调执行
创建请求interface
- http方法注解,用于标识请求的方法 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 ,FormUrlEncoded,Field,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这一步,通过动态代理返回一个实例,通过RequestFactory解析注解构建Request。Call,Callback,Response都有一层封装来隔离。调用callFactory,传入Request返回Call,调用Call返回Response,然后通过Converter来逆序列化body为entity
- 解析方法注解和参数注解,ServiceMethod,RequestFactory
- HttpServiceMethod#createCallAdapter,#createResponseConverter,通过Retrofit里的factory创建对应的实例
- HttpServiceMethod#invoke返回结果。
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
- OkHttpCall负责构建Call
- 最终调的是DefaultCallAdapterFactory#ExecutorCallbackCall,默认把Call转化并代理,目前其实只干了一件事,因为OkHttp默认在非UI线程回调callback,ExecutorCallbackCall在UI线程分发
call#enqueue(callback)
public interface Callback<T> {
void onResponse(Call<T> call, Response<T> response);
void onFailure(Call<T> call, Throwable t);
}