官网:http://square.github.io/retrofit/
github地址:https://github.com/square/retrofit
最近,在自己的工程里用到了Retrofit,确实好用;这几天,也抽空闲的时间,看了它的源码,学到了一些东西。今天,就抽时间来写这篇博客,来分享些我从Retrofit上学到的东西,比如Java类型(这里的类型不是指基本类型)、动态代理。
关于Retrofit 2.0的使用,大家可以看官网的使用介绍或者这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)(这篇博客很详细)。
点开工程里的Retrofit(我这版本是2.3)的依赖包
http包下全是注解,所以不用管;大概有17个类文件,其中有4个接口。先看看类与类之间的关系
上面这三张图,是粗略画的UML类图(并不完全),是不是对类的关系有了大概地了解。
关于代码分析,推荐这篇博客(深入剖析 Retrofit 2.0 源码),就不介绍了;个人觉得源码应该自己抽时间看。看别人的分析,虽然很节约时间,但是收获相对地也会变少;因为每个人的认知不同,获得的收获肯定也不一样。如果有时间的话,还是自己看最好。
在图1和图2中,分别有个CallAdapter.Factory和Converter.Factory,它们都是抽象类,分别写在接口CallAdapter与Converter中;是不是很意外?(反正,我是很意外)还有这种写法,在接口中写了个类。
public interface CallAdapter<R, T> {
Type responseType();
T adapt(Call call);
abstract class Factory {
public abstract @Nullable 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);
}
}
}
我们经常在接口中,写未实现的方法和常量;原来,接口中也可以写一个内部类;这里的抽象类Factory就是用来构建实现了CallAdapter接口的类实例,其作用类似于工厂。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)// 设置网络请求的Url地址
.callFactory(client)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
public interface Request {
/***
* 请求当前城市的正在热映的电影
* @param city 城市
* @return
*/
@GET("v2/movie/in_theaters")
Observable getHitMessage(@Query("city") String city);
}
调用create()
转入个class文件。用到这个方法的时候,第一时间就想到了反射机制(对Java反射机制不是很了解的朋友,可以参考这篇博客Java类型信息(Class对象)与反射机制;但是Request是个接口,我根本没有实现它,Retrofit是会怎么处理呢?这是我当时的疑问。
public T create(final Class 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, @Nullable Object[] args)
throws Throwable {
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod
在create方法中返回Proxy.newProxyInstance;Proxy是什么?第一次见,点开它;原来它在java.lang.reflect包下,其作用就是代理,也就是动态代理。这个类的用法,大家可以看Java文档或者这篇博客(动态代理的实现)。
在看Utils类文件中的getRawType方法时
static Class> getRawType(Type type) {
checkNotNull(type, "type == null");
if (type instanceof Class>) {
// Type is a normal class.
return (Class>) type;
}
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
Type rawType = parameterizedType.getRawType();
if (!(rawType instanceof Class)) throw new IllegalArgumentException();
return (Class>) rawType;
}
if (type instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) type).getGenericComponentType();
return Array.newInstance(getRawType(componentType), 0).getClass();
}
if (type instanceof TypeVariable) {
return Object.class;
}
if (type instanceof WildcardType) {
return getRawType(((WildcardType) type).getUpperBounds()[0]);
}
throw new IllegalArgumentException("Expected a Class, ParameterizedType, or "
+ "GenericArrayType, but <" + type + "> is of type " + type.getClass().getName());
}
看到了几个陌生的类,比如GenericArrayType、TypeVariable等,这几个类也是在java.lang.reflect包下。通过Java文档介绍和网上的博客,get到了一个新概念(以前不知道,还有这种东西),就是Java Type(推荐这篇博客Java Type 详解);这里类型并不是指基本类型,比如int、long等。