转载请注明出处:https://blog.csdn.net/m0_37840695/article/details/119773710
本文源码版本是2.3.0,是一个mavan项目,建议用IDEA打开。
1.官网介绍

2.源码解析
我们根据这段代码来看源码:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
GitHubService service = retrofit.create(GitHubService.class);
Call<List<Repo>> reposCall = service.listRepos("octocat");
List<Repo> repos= reposCall.execute().body();//同步
reposCall.enqueue(new Callback<List<Contributor>>() {//异步
@Override
public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
//回到了主线程
}
@Override
public void onFailure(Call<List<Repo>> call, Throwable t) {
//回到了主线程
}
});
retrofit实例化
这个Platform类我们下文会分析。
这个BuiltInConverters基本不会用于生产中,也没啥营养,这里就不展示了。
addConverterFactory(GsonConverterFactory.create())




GitHubService service = retrofit.create(GitHubService.class);
通过java动态代理生成的代理类Proxy0:
public class Proxy0 extends Proxy implements GitHubService {
//第一步, 生成构造器
protected Proxy0(InvocationHandler h) {
super(h);
}
//第二步, 生成静态域
private static Method m1; //hashCode方法
private static Method m2; //equals方法
private static Method m3; //toString方法
private static Method m4; //...
//第三步, 生成代理方法
@Override
public int hashCode() {
try {
return (int) h.invoke(this, m1, null);
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
@Override
public boolean equals(Object obj) {
try {
Object[] args = new Object[] {obj};
return (boolean) h.invoke(this, m2, args);
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
@Override
public String toString() {
try {
return (String) h.invoke(this, m3, null);
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
@Override
public List<Repo> listRepos(String user) {
try {
//构造参数数组, 如果有多个参数往后面添加就行了
Object[] args = new Object[] {user};
return (List<Repo>)h.invoke(this, m4, args);
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
//第四步, 生成静态初始化方法
static {
try {
Class c1 = Class.forName(Object.class.getName());
Class c2 = Class.forName(GitHubService.class.getName());
m1 = c1.getMethod("hashCode", null);
m2 = c1.getMethod("equals", new Class[]{Object.class});
m3 = c1.getMethod("toString", null);
m4 = c2.getMethod("save", new Class[]{GitHubService.class});
} catch (Exception e) {
e.printStackTrace();
}
}
}
Call<List<Repo>> reposCall = service.listRepos("octocat");
这行代码将触发invocationHandler.invoke:
3.问题列表
3.1 retrofit是线程安全的吗?
3.2 我们发起网络请求是传入的CallBack会因为强引用而内存泄漏吗?
所以是有可能引起内存泄漏的?错!
所以并不会导致内存泄漏 。
3.3 retrofit在运行时通过java的动态代理生成代理类,并解析被代理方法的注解生成serviceMethod,并将serviceMethod缓存,这种方式对比EventBus通过注解处理器在编译期解析注解并生成订阅点并保持到index(Java)文件中,两种方式孰优孰劣?
首先,我们该用第二种方式肯定也可以,而且只有优点没有缺点,具体参考我的EventBus源码解析。
其次,当前这种方式,有什么缺点吗?
通过java的动态代理生成代理类,只需要13ms左右(参考),性能很好。在invocationHandler.invoke方法中,解析被代理方法的注解生成serviceMethod,不存在CPU密集型操作,更不存在IO操作,是不耗时的:
应该说当前方式性能也不差,我猜这也是为啥作者没有改用注解处理器的原因。
推荐: