最简单的okhttp+retrofit2使用demo
retrofit = new Retrofit.Builder()
.baseUrl("https://api.douban.com/v2/")
.build();
service= retrofit.create(RetrofitService.class);
Call<Book> call = service.getSearchBook("金瓶梅",null, 0, 1);
call.enqueue(new Callback<Book>(){
@Override
public void onResponse(Call<Book>call, Response<Book> response) {
text_tv.setText(response.body()+"");
}
@Override
public void onFailure(Call<Book>call, Throwable t) {
}
});
这里retrofit使用了build模式,点进去可以看到
public Builder() { this(Platform.get()); }
Builder函数
Builder(Platform platform) { this.platform = platform; // Add the built-in converter factory first. This prevents overriding its behavior but also // ensures correct behavior when using converters that consume all types. converterFactories.add(new BuiltInConverters()); }
这里使用了一个Platform.get()函数,查阅资料可以得知,这个Platform.get()是获得平台信息的函数(平台可以是android或者是java8)。除此之外还有一个converterFactories.add(new BuiltInConverters());这个函数的主要作用是添加了一个Converter.Factory工厂类。在retrofit的build函数中有解释
public Retrofit build() { if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory == null) { callFactory = new OkHttpClient(); } Executor callbackExecutor = this.callbackExecutor; if (callbackExecutor == null) { callbackExecutor = platform.defaultCallbackExecutor(); } // Make a defensive copy of the adapters and add the default Call adapter. List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories); adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); // Make a defensive copy of the converters. List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories); return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly); }
没理解错的话,应该是一个把返回结果转换的工厂。另外那个CallAdapter.Factory应该是添加Call或者Rxjava中Observer的类,默认情况的话,应该是Call。
而这个默认添加的BuiltInConverters再请求情况的状态下,主要去除future I/O,其实啥也没做就是吧response又吐出来了。
回到retrofit的build,这里这个baseUrl是必须的,不然会报错,源码里是这样的
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); }
这样的话,一个retrofit对象就新建好了。
然后就到了新建接口的对象service了,源码里是这样的
@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety. public <T> T create(final Class<T> service) { Utils.validateServiceInterface(service); if (validateEagerly) { eagerlyValidateMethods(service); } 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, 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)) { return platform.invokeDefaultMethod(method, service, proxy, args); } ServiceMethod serviceMethod = loadServiceMethod(method); OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall); } }); }
首先这个validateEagerly来自于Retrofit对象的自定义。好像预设做了点什么,实际测了一下好像并没有什么区别。
讲真这里这个原理我不是很懂。好像利用了反射和代理模式相关的知识,需要单独学一下,暂时先放一下。
这里的SetviceMethod是retrofit的主要功能实现载体。
ServiceMethod:从接口方法到Http请求(OKHttp的Call)的转换器,也是使用的构造器模式。