直接上图:
OkHttpClient 也是外观类,参数太多不好画,也没必要.retrofit :是一个对网络库的使用进行了封装的第三方库.
我们只需要操作 retrofit实例就可以得到你想要的结果,屏蔽内部原理,使用更加简单.并且提供了拔插式的配置如:
OkHttpClient.Call.factory 网络实现,Converter.Factory 转换工厂,CallAdapter.Factory适配工厂.几乎可以是开箱即用(默认配置).什么都有两面性:在这中间使用了反射,动态代理,缓存.还有使用了静态代理使得方法的调用和类增多必然有性能消耗.这里属性和类都在哪里起作用的呢:
Map<Method,ServiceMethod<?,?>>serviceMethod 在使用retrofit.create(..)时可以会起到作用:
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);//判断service 是否为接口或者继承其他接口是good bye
if (validateEagerly) { //是否提前将接口的所有方法解析进行缓存,默认false
eagerlyValidateMethods(service);//这里起了作用
}
//重点来 使用动态代理,这种代理只能代理的是接口类.使用代理实例调用任何方法都执行下面invoke(....)方法
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 the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) { //接口没有这种情况吧
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) { //默认false
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);//这里主要进行//了判断是否有缓存,有返回 .没有,解析注解数据,和找到合适CallAdapter Coverter并缓存,没有找到合适抛异常
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);//这里//将传过来的参数,在调用enqueque(..)和execute()会创建一个Recall
return serviceMethod.callAdapter.adapt(okHttpCall); //通过适配模式进行适配成你想要的实例
}
});
}
在ServiceMthod 实例中存放着 对应方法解析数据,和一个分配好的CallAdapter.Factory ,Converter.Factory,并将方法参数和ServiceMthod 实例传递给OkHttpCall,在调用网络请求方法时,会通过这些参数创建Request实例并使用OKHttpClient.newCall(Request)创建RealCall对象
HttpUrl :
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
HttpUrl httpUrl = HttpUrl.parse(baseUrl); //解析 baseUrl是否合法正确
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl); //检验最后一个字符是否为 "/" 否抛异常
}
在构建 Request 也用到了
HttpUrl url;
HttpUrl.Builder urlBuilder = this.urlBuilder; //有没有@Url 参数注解
if (urlBuilder != null) {
url = urlBuilder.build(); //有就使用这个
} else {
// No query parameters triggered builder creation, just combine the relative URL and base URL.
//noinspection ConstantConditions Non-null if urlBuilder is null.
url = baseUrl.resolve(relativeUrl); //没有将使用这个baseUrl+.....
if (url == null) {
throw new IllegalArgumentException(
"Malformed URL. Base: " + baseUrl + ", Relative: " + relativeUrl);
}
}
List<Converter.Factory> 不同OkHttpClient 拦截器,只会从挑选一个Converter.Factory. 在同步方法请求完成用到. 因为他适配的是这个OkhttpCall所以查看他 execute方法():
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else {
throw (RuntimeException) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();//创建一个真实RealCall 对象(默认Okhttpclient)
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
//这里使用serviveMethod.toResponse,其实就是调用已经分配好converter.convert(..)
return parseResponse(call.execute()); //通过RealCall调用OkHtppClient 同步网络实现方法
}
其他的地方看着办吧,反正用不着.当然也可以直接看Converter.Factory 方法解释就知道了
异步也是一样的.但是结果回调使用Executor 分派到ui线程运行
实现:
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor(); //andriod 平台的使用这个
}
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
很简单 直接用handler 就行了
OkHttpClient.Call.Factory :网络实现.
List<CallAdapter.Factory> 跟Convertor.Factory集合是一样的, 在第一个已经用到了.作用:将OkHttpCall 适配如:默认的将适配成retrofit 包下的ExecutorCallbackCall,使用RxJava将适配成Observable.