retrofit 源码分析
callAdater可以设置RxJava2CallAdapter,目前只可用这个adapter,支持rxjava2的操作;convertAdater可以使用多种进行操作。
调用例子:
Retrofit retrofit = builder.baseUrl("https://api.github.com") .client(client) .build(); return retrofit.create(serviceClass);
通过创建Retrofit分析得到,数据的内容为public <T> T create(final Class<T> service) {};传入的参数是一个类型Class的类型,返回的也是这个class实例对象,这里返回的
是serviceClass类对象。这个对象未进行初始化操作,就是里面的接口的函数实例未进行初始化。会使用动态代理创建一个newProxyInstance对象,通过传入的InvocationHandler类进行操作。
retrofit 创建类变量,创建时需要下面的变量进行初始化,callFactory通过client的方法进行设置;baseurl就是链接的网址;converterFactories转换发送和接收的json报文信息,或者组包
请求的数据包。adapterFactories执行rxjava的RxJava2CallAdapterFactory、callbackExecutor平台创建的执行回掉,普通的java平台和安卓平台;
reponse 返回的convert匹配方法,通过判断
通过日志可以监控到,retrofit默认的有一个BuiltInConverters
public abstract io.reactivex.Single com.seuic.getuser.EventService.getFollowing(long)传入的method是一个抽象的方法,返回的结果是servicemethod的对象,在创建servicemethod的时候,会初始化所有参数,各种adapter,具体的详细field如下图所示:
ServiceMethod(Builder<R, T> builder) { this.callFactory = builder.retrofit.callFactory(); this.callAdapter = builder.callAdapter; this.baseUrl = builder.retrofit.baseUrl(); this.responseConverter = builder.responseConverter; this.httpMethod = builder.httpMethod; this.relativeUrl = builder.relativeUrl; this.headers = builder.headers; this.contentType = builder.contentType; this.hasBody = builder.hasBody; this.isFormEncoded = builder.isFormEncoded; this.isMultipart = builder.isMultipart; this.parameterHandlers = builder.parameterHandlers; }
servicemethod类提供了创建okhttp的请求组包,在okhttpcall中被调用,toRequest函数返回一个请求的 对象;
CallExecuteObservable》OkHttpCall》servicemethod里的okhttp的client和request
private okhttp3.Call createRawCall() throws IOException { Request request = serviceMethod.toRequest(args); okhttp3.Call call = serviceMethod.callFactory.newCall(request); if (call == null) { throw new NullPointerException("Call.Factory returned null."); } return call; }
okhttp的call是在rxjava2 calladpter运行的。执行的结果如下图所示
retrofit http请求返回类型说明,返回类型通过类型解析获取到,最终返回的类型为Page<user>的类
public interface EventService { @GET("users/{username}/received_events") Single<Response<Page<User>>> getUserRecievedEvents(@Path("username") String username, @Query("page") long page); @GET("/user/following") Single<Response<Page<User>>> getFollowing(@Query("page") long page); }
关于convertadpater匹配说明,实际的使用中,可以设置多个convertadpater,但是最终的选择是根据返回的类型进行解析选定的,就是
int start = converterFactories.indexOf(skipPast) + 1; for (int i = start, count = converterFactories.size(); i < count; i++) { Converter<ResponseBody, ?> converter = converterFactories.get(i).responseBodyConverter(type, annotations, this); if (converter != null) { //noinspection unchecked return (Converter<ResponseBody, T>) converter; } }
type:当前请求返回的类型,本例中就是page,通过代码跟踪可以看到,循环的匹配查找当前的adpater里类型与type是否一致,不一致就返回null,继续寻找下一个,直接遇到moshi这个对象,直接把type传入进去,创建一个转换的adatper,可以将json转换成指定的class 对象,所以这里可以添加多个convertadatper,可以在需要用的时候直接调用;如果不添加,会默认一个convert,用户可以写自己的convert,然后添加进去。
当且仅当调用everntservice里面的函数的时候,才会运行调用InvocationHandler里面的invoke函数,在创建retrofit接口实例的时候不会调用invoke回掉
1、retrofit模块对象说明,主要提供设置请求地址设置,创建callAdapter和convertAdpter对象的实例化。以及create实现的动态代理调用,create是调用的核心代码,实现一个接口的实例。
2、ServiceMethod对象提供请求和解析的功能,给okhttp的回掉使用;生成http请求的body,同时解析返回的body数据;在build的时候解析http数据包的各个字段,例如
head和body等信息,创建http请求时需要该字段。
OkHttpCall类继承了call接口,该对象主要是okhttp请求操作,对call接口的实现,该接口提供给rxjavaAdapter使用