Retrofit详解(一)(Retrofit创建过程)
2016-04-18 14:43
477 查看
作为一个coder 最悲哀的莫过于知其然,不知其所以然。
闲暇之余,研究研究Retrofit源码,为了防止大篇幅的代码,看得头晕眼花,这章仅仅详细介绍Retrofit 的创建过程。Retrofit使用方法这里就不介绍了,请看我前面写的博客。
首先贴上需要提前展示的APIService:
如上所述使用retrofit 访问网络就是这么简单,那么Retrofit框架怎样实现的呢?请往下看
Retrofit类有一个静态内部类Builder,调用Builder的build()方法就能生成Retrofit对象,看看它的成员变量,是不是觉得网络访问的几要素都具备了?
网络请求工具、线程处理工具、网络访问回调处理工具、网络访问结果解析工具。
首先来看platform变量,顾名思义与平台相关:
第一个默认就是查找是否是Andriod平台,当然后面还有Java8,IOS的Platform,有兴趣可以查看源码,先来看看Android:
是不是看到熟悉的东西了,没错,它就是Handler,现在是不是觉得Retrofit底层也是利用了Handler?
仔细查看相关源码就能得出以下描述:
调用默认的Retrofit.Builder()方法默认会自动判断platform为Andriod,然后赋值给Retrofit.Builder类的platform变量。
.baseUrl(String url)方法解析我们传入的url参数生成一个HttpUrl对象存放于Retrofit. Builder类的成员变量baseUrl中。
.addConverterFactory方法添加相应结果解析器,存放于Retrofit.Builder类的converterFactories集合中。从Builder的构造方法可以看出创建Builder的时候会自动添加一个默认的ConvertFactory,我们也可以调用多次addConverterFactory添加多个ConvertFactory,处理结果的时候会按添加顺序优先匹配,一旦匹配上前面的,就丢弃后面的,当然我们能添加自己定义的ConvertFactory只要继承Converter.Factory,详细放在后面讲解。
.addCallAdapterFactory方法添加访问处理适配器,存放于Retrofit.Builder类的adapterFactories集合中。
.client方法用于添加网络访问工具OKHttpClient,保存在Retrofit.Builder类的callFactory变量中.
调用.build()方法,通过platform设置Retrofit.Builder类的callbackExcutor变量,然后最终会生成一个Retrofit对象。
再来看看Retrofit的成员变量和构造方法:
这就像是将它的静态内部类Builder里的成员变量搬过来的。serviceMethodCache是一个存储方法(当然是我们定义在接口里的方法啦)Map,后面会用到。
到这里Retrofit总算是被我们给new出来了,下一章就该讲解我们需要的Api Service的创建以及访问了。
闲暇之余,研究研究Retrofit源码,为了防止大篇幅的代码,看得头晕眼花,这章仅仅详细介绍Retrofit 的创建过程。Retrofit使用方法这里就不介绍了,请看我前面写的博客。
首先贴上需要提前展示的APIService:
public interface UserService { @POST(Constants.URL_UPDATE_USER_LIST) Observable<BaseResponse<List<User>>> updateUserList(@Query("userList") String userList); }
Retrofit retrofit = new Retrofit.Builder() .baseUrl(getEndPoint(t)) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(clientBuilder.build()) .build(); service = retrofit.create(t);
如上所述使用retrofit 访问网络就是这么简单,那么Retrofit框架怎样实现的呢?请往下看
Retrofit类有一个静态内部类Builder,调用Builder的build()方法就能生成Retrofit对象,看看它的成员变量,是不是觉得网络访问的几要素都具备了?
网络请求工具、线程处理工具、网络访问回调处理工具、网络访问结果解析工具。
public static final class Builder { private Platform platform; private okhttp3.Call.Factory callFactory; private HttpUrl baseUrl; private List<Converter.Factory> converterFactories = new ArrayList<>(); private List<CallAdapter.Factory> adapterFactories = new ArrayList<>(); private Executor callbackExecutor; private boolean validateEagerly; 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()); } public Builder() { this(Platform.get()); }
首先来看platform变量,顾名思义与平台相关:
class Platform { private static final Platform PLATFORM = findPlatform(); static Platform get() { return PLATFORM; } private static Platform findPlatform() { try { Class.forName("android.os.Build"); if (Build.VERSION.SDK_INT != 0) { return new Android(); } } catch (ClassNotFoundException ignored) { } try { Class.forName("java.util.Optional"); return new Java8(); } catch (ClassNotFoundException ignored) { } try { Class.forName("org.robovm.apple.foundation.NSObject"); return new IOS(); } catch (ClassNotFoundException ignored) { } return new Platform(); }
第一个默认就是查找是否是Andriod平台,当然后面还有Java8,IOS的Platform,有兴趣可以查看源码,先来看看Android:
static class Android extends Platform { @Override public Executor defaultCallbackExecutor() { return new MainThreadExecutor(); } @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) { 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,现在是不是觉得Retrofit底层也是利用了Handler?
仔细查看相关源码就能得出以下描述:
调用默认的Retrofit.Builder()方法默认会自动判断platform为Andriod,然后赋值给Retrofit.Builder类的platform变量。
.baseUrl(String url)方法解析我们传入的url参数生成一个HttpUrl对象存放于Retrofit. Builder类的成员变量baseUrl中。
.addConverterFactory方法添加相应结果解析器,存放于Retrofit.Builder类的converterFactories集合中。从Builder的构造方法可以看出创建Builder的时候会自动添加一个默认的ConvertFactory,我们也可以调用多次addConverterFactory添加多个ConvertFactory,处理结果的时候会按添加顺序优先匹配,一旦匹配上前面的,就丢弃后面的,当然我们能添加自己定义的ConvertFactory只要继承Converter.Factory,详细放在后面讲解。
.addCallAdapterFactory方法添加访问处理适配器,存放于Retrofit.Builder类的adapterFactories集合中。
.client方法用于添加网络访问工具OKHttpClient,保存在Retrofit.Builder类的callFactory变量中.
调用.build()方法,通过platform设置Retrofit.Builder类的callbackExcutor变量,然后最终会生成一个Retrofit对象。
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); }
再来看看Retrofit的成员变量和构造方法:
public final class Retrofit { private final Map<Method, ServiceMethod> serviceMethodCache = new LinkedHashMap<>(); private final okhttp3.Call.Factory callFactory; private final HttpUrl baseUrl; private final List<Converter.Factory> converterFactories; private final List<CallAdapter.Factory> adapterFactories; private final Executor callbackExecutor; private final boolean validateEagerly; Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl, List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories, Executor callbackExecutor, boolean validateEagerly) { this.callFactory = callFactory; this.baseUrl = baseUrl; this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site. this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site. this.callbackExecutor = callbackExecutor; this.validateEagerly = validateEagerly; }
这就像是将它的静态内部类Builder里的成员变量搬过来的。serviceMethodCache是一个存储方法(当然是我们定义在接口里的方法啦)Map,后面会用到。
到这里Retrofit总算是被我们给new出来了,下一章就该讲解我们需要的Api Service的创建以及访问了。
相关文章推荐
- 基于CentOS的MySQL学习补充三--使用Shell批量创建数据库表
- Android复习之单例模式
- sqlite3的使用(iOS嵌入式关系数据库)
- 详解Linux2.6内核中基于platform机制的驱动模型
- 初始化job,并分析svn日志--initNEW1-UFT.bat
- UML类图实例
- Win7提示诊断策略服务未运行无法诊断检查网络解决方法
- netstat 命令详解
- 利用Python获取赶集网招聘信息前篇
- 线程池参数详解
- 重建二叉树
- Coursera Chaptereight:Lists Assignment 8.4
- 让多个 DIV 高度相同
- 模块标识
- 昨日顺利跑完半马~总结一下
- C#:Winform技巧
- python升级后yum不能使用报错 File “/usr/bin/yum”, line 30
- 【C语言】str类与men库函数的实现(如:strcpy,strcmp,strstr,strcat,memmove,memcpy)
- 大数运算(小项目)
- mac 下eclipse 安装svn插件