retrofit源码解析
- retrofit使用方式
- retrofit源码剖析
retrofit使用方式: 3个步骤
- 在retrofit中通过一个接口作为http请求的api接口
- 2.创建一个retrofit实例
- 3.调用api的接口(通过retrofit实例传入java定义的接口,调用接口里面的方法)
1.接口类:
public interface NewApi{
@GET("REPOS/{owner}/{repo}/contributors")
Call<ResponseBody> contributorsBySimpleGetCall(@Path("owner") String owner,@Path("repo") String repo);
}
创建一个java接口,定义一个请求方法,然后用注解的形式告诉这是一个Get请求。定义Url时(即注解后面的参数),动态的获取url的方式来进行的
2.创建实例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")//这里不是完整的
.build();
NewApi repo = retrofit.create(NewApi.class);
3.调用api的接口
retrofit2.Call<ResponseBody> call = repo.contributorsBySimpleGetCall("userName","path");
call.enqueue(new retrofit2.Callback<ResponseBody>(){
public void onResponse(retrofit2.Call<ResponseBody> call,retrofit2.Response<ResponseBody> response){
//
}
public void onFailure(retrofit2.Call<ResponseBody> call,Throwable t){
}
})
2.retrofit源码剖析
动态代理模式:
- 首先,通过method把它转换成ServiceMethod;
- 然后,通过serviceMethod,args获取到okHttpCall对象;
- 最后,再把okHttpCall进一步封装并返回Call对象。
(把okHttpCall传给Adapter来进行retrofit的网络数据获取)
- 最后,再把okHttpCall进一步封装并返回Call对象。
Retrofit对象build构造模式创建:
图:
- 构造方法:
1.传入平台信息
2.将内置的转换器工厂添加到convertFactories里面,它的主要作用就是当使用多种转换器的时候,能够正确的引导retrotfit网络请求所真正需要的数据转换器
- 构造方法:
Retrofit build()方法
baseUrl == null;
//1.判空操作。即使没有使用retrofit也必须传入,不能为空
okhttp3.Call.Factory callFactory = this.callFactory;
//2.它的作用是用来数据转化的,请求网络会获取数据,这些数据会在callFactory这里转换成我们需要的数据类型 ,如何做到的?
if(callFactory == null){
callFactory = new OkHttpClient();
}
//3.创建一个网络请求客户端,添加我们想要的属性
Executor callbackExecutor = this.callbackExcutor;
//4.回调的执行者,我们所有的Http的call网络请求,从网络获取的数据是在子线程中进行的,子线程的数据需要在ui线程中显示,这个功能由Executor来做。
if(callbackExecutor == null){
callbackExecutor = platform.defaultCallbackExecutor();
}
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
List<Converter.Factory> convertFactories = new ArrayList<>(this.convertFactories);
return new Retrofit(callFactory,baseUrl,convertFActories,adapterFactories,callbackExecutor,validateEagerly);
- retrofit实例对象craeate(接口.class)
动态代理在create方法中实现的
图:
- retrofit实例对象craeate(接口.class)
public <T> T create(final Class<T> service){
xxx
return (T)Proxy.newProxyInstance(service.getClassLoader(),new Class<?>[]{service},
new InvocationHandler(){
private final Platform platform = Platform.get();
public Object invoke(Object proxy,Method method,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<Object,Object> serviceMethod = (ServiceMethod<Object,Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod,args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
}
)
}
怎么实现的,是怎么把定义的java接口转换成一个实例,然后来请求这个实例当中的方法。返回值 return xx
Proxy代理.newProxyInstance会返回一个代理实例,
需要传入1.classLoader(类加载器),
2.以及类的本身class,
3.InvocationHandler处理器(invocation翻译:处理)
invoke方法()
每当调用代理类方法的时候,这个方法都会被执行
参数:Object proxy,Method method,Object[] args
方法,方法参数(object数据)
最精髓的地方:
ServiceMethod<Object,Object> serviceMethod = (ServiceMethod<Object,Object>) loadServiceMethod(method);
//
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod,args);
return serviceMethod.callAdapter.adapt(okHttpCall);
其中ServiceMethod<?,?> loadServiceMethod(Method method){
ServiceMethod<?,?> result = serviceMethodCache.get(method);
if(result !=null) return result;
synchronized(serviceMethodCache){
result = serviceMethodCache.get(method);
if(result == null){
result = new ServiceMethod.Builder<>(this,method).build();
//使用Build模式
serviceMethodCache.put(method,result);
//缓存
}
}
return result;
}
网友评论