本平台的文章更新会有延迟,你们能够关注微信公众号-顾林海,包括年末前会更新kotlin由浅入深系列教程,目前计划在微信公众号进行首发,若是你们想获取最新教程,请关注微信公众号,谢谢!java
在上章节《Android小知识-剖析Retrofit中的网络请求流程以及相关参数》中介绍了Retrofit的成员变量,以及静态内部类Builder中的成员变量,本节继续讲解Builder类中的相关方法。web
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://icould.glh/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
复制代码
经过Builder的baseUrl方法来设置http的基地址,先进入baseUrl方法。json
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
复制代码
在baseUrl方法中,将传入的String类型的baseUrl经过HttpUrl的parse方法转换成HttpUrl对象,将转换后的httpUrl实例传入baseUrl方法,注意这里传入baseUrl方法的是HttpUrl对象,咱们继续看baseUrl(HttpUrl)方法。数组
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
复制代码
经过checkNotNull方法判断HttpUrl对象是否为空,接着经过HttpUrl的pathSegments()方法将url拆分红多个独立的碎片,为了方便比较,将建立Retrofit实例贴出来:服务器
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://icould.glh/")
复制代码
经过baseUrl方法设置http的url时,在最后是以'/'反斜杠结尾的,下面的if语句中判断拆分后的最后字符串是否为空,拆分后的数组最后一个为空,说明http的url是以'/'结尾,反之http的url不是以'/'结尾,就会抛出异常,最后将baseUrl赋值给Builder的成员变量baseUrl。微信
介绍完baseUrl方法,继续看下一个方法addConverterFactory方法:网络
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://icould.glh/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
复制代码
addConverterFactory方法是用于设置数据解析器,进入addConverterFactory方法看看到底作了哪些操做。ide
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
复制代码
addConverterFactory方法所作的工做很简单,就是将factory添加到数据解析器工厂的集合中。回到前面addConverterFactory方法,看到传入的是GsonConverterFactory对象,而GsonConverterFactory对象是经过GsonConverterFactory的get()方法建立的,点进去看下。函数
public static GsonConverterFactory create() {
return create(new Gson());
}
复制代码
create方法内部先是建立了Gson对象,这个Gson就是goole提供的Gson,用于解析json数据用的,建立完Gson对象后调用create方法并传入刚建立后的Gson对象。ui
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}
复制代码
方法很简单,建立一个GsonConverterFactory对象并返回,咱们进入GsonConverterFactory的构造函数中。
private final Gson gson;
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
复制代码
GsonConverterFactory的构造函数只作了赋值操做,将建立好的Gson对象赋值给GsonConverterFactory的成员变量gson。
介绍完addConverterFactory方法后,接着看addCallAdapterFactory方法:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://icould.glh/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
复制代码
addCallAdapterFactory方法用于设置适配的平台,这里使用的是RxJava平台,咱们看下addCallAdapterFactory的具体操做。
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
callAdapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
复制代码
代码仍是很简单,就是将factory添加到适配器工厂的集合中去。回到前面,看看addCallAdapterFactory方法传入的这个Factory,是经过RxJavaCallAdapterFactory工厂类的create()方法来建立的。
public static RxJavaCallAdapterFactory create() {
return new RxJavaCallAdapterFactory(null, false);
}
复制代码
create方法内部直接经过new关键字建立了RxJavaCallAdapterFactory对象。
public final class RxJavaCallAdapterFactory extends CallAdapter.Factory {
...
}
复制代码
RxJavaCallAdapterFactory继承了CallAdapter的内部类Factory。
先看CallAdapter的做用,CallAdapter做用就是经过Retrofit中Call转换成Java对象,Retrofit中的Call对象和OkHttp中的Call对象是不同的,Retrofit中的Call是对OkHttp中的Call进行了封装,也就是说经过Retrofit来进行网络请求,最终都是经过OkHttp来进行请求的。在转换Java对象前,须要先建立Retrofit中的Call对象,而后经过Call对象发送http请求,服务器会返回响应的数据,这个时候经过converter数据转换器,将服务器返回的Response转换成咱们须要的Java对象。
public interface CallAdapter<R, T> {
Type responseType();
T adapt(Call<R> call);
}
复制代码
在CallAdapter接口中定义了一个responseType()方法并返回Type类型,这个方法的做用就是返回解析后的类型。看下面网络请求接口:
public interface NetworkInterface {
@GET("news/newsDetail")
Call<MyResponse> getNewsDetails(@QueryMap Map<String,String> map);
}
复制代码
CallAdapter接口中的responseType方法返回的就是MyResponse这个类型的对象。
public interface CallAdapter<R, T> {
Type responseType();
T adapt(Call<R> call);
}
复制代码
继续看第二个方法adapt,这里的泛型T是指须要转换接口的返回类型,adapt方法传入一个Call对象,这个Call对象就是OkHttp的Call对象,若是对应的是RxJava的话,这里的T对应的就是RxJava当中的类型。
继续看CallAdapter内部类Factory:
public interface CallAdapter<R, T> {
...
abstract class Factory {
public abstract @Nullable retrofit2.CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
Retrofit retrofit);
...
protected static Class<?> getRawType(Type type) {
return Utils.getRawType(type);
}
}
}
复制代码
get方法的做用是根据接口的返回类型以及注解类型来获得实际须要的CallAdapter;getRawType方法返回的是原始的类型。
RxJavaCallAdapterFactory实现Factory抽象类,用来提供具体的适配逻辑,回到RxJavaCallAdapterFactory,先看get方法的实现:
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
...
return new RxJavaCallAdapter(responseType, scheduler, isAsync, isResult, isBody, isSingle,
false);
}
复制代码
在get方法中,先经过getRawType拿到原始数据类型,经过这个原始数据类型进行各类设置,最后建立RxJavaCallAdapter对象并返回。建立完RxJavaCallAdapter对象后,最终调用adapt方法将咱们的Call请求转换成每个平台所适用的类型。adapt方法在接口CallAdapter中定义的,在源码中找到RxJavaCallAdapter实现了CallAdapter接口,咱们看看RxJavaCallAdapter中的adapt实现。
@Override public Object adapt(Call<R> call) {
Observable.OnSubscribe<Response<R>> callFunc = isAsync
? new CallEnqueueOnSubscribe<>(call)
: new CallExecuteOnSubscribe<>(call);
Observable.OnSubscribe<?> func;
if (isResult) {
func = new ResultOnSubscribe<>(callFunc);
} else if (isBody) {
func = new BodyOnSubscribe<>(callFunc);
} else {
func = callFunc;
}
Observable<?> observable = Observable.create(func);
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isSingle) {
return observable.toSingle();
}
if (isCompletable) {
return observable.toCompletable();
}
return observable;
}
复制代码
使用过RxJava的同窗应该对上面的代码很是熟悉了,将咱们传入的OkHttp的Call对象设置给OnSubscribe对象,接着建立Observable被观察者的实例,并将OnSubscribe与被观察者绑定,最后判断scheduler调度器是否为空,若是不为空,就调用observable的subscribeOn方法在指定的调度器执行操做。关于RxJava的相关知识后面会另开文章进行讲解,这里你们先有个印象,知道总体的流程便可。
到这里baseUrl、addConverterFactory以及addCallAdapterFactory方法就介绍完毕。
搜索微信“顾林海”公众号,按期推送优质文章。