xUtils3源码分析(一):view的绑定
概述
xUtils3是国人开发的一款功能丰富的Android快速开发框架,值得研究下。
zip包下载:[ZIP]
xutils主要分以下几个模块
- 视图绑定模块
- 网络请求模块
- 数据库模块
- 图片加载模块
我们将逐一透过源码分析,本文分析视图绑定模块,包含View
的注入和View
事件的注入。
我们将项目导入AndroidStudio,项目结构:

xutils为项目源码,sample为使用方法举例。
我们通过分析sample这个示例项目来分析xutils的内部细节。
首先我们看看MyApplication
这个类:

xUtils3在初始化的时候必须在自定义的Application
中来完成初始化,代码为x.Ext.init(this);
,首先就涉及到了这个x
类,我们打开看看:
/**
* Created by wyouflf on 15/6/10.
* 任务控制中心, http, image, db, view注入等接口的入口.
* 需要在在application的onCreate中初始化: x.Ext.init(this);
*/
public final class x {
...省略代码
}
通过类注释我们可以看到x
类是所有模块的入口。
那我们看看x.Ext
这个内部类:

该类提供了一系列的静态成员变量,和对应的set
方法,对应了xutils
提供的几个功能模块。
看看init
方法:

很明显将Application
绑定到app
上,方便全局调用。
接下来我们分模块说明:
View注入
我们找到一个BaseActivity
:

在Activity
的onCreate
方法中,调用:x.view().inject(this)
来完成视图注解框架的初始化。
看看view()
方法做了什么:

该方法是用来进行Ext.viewInjector
的初始化的,那么我们到ViewInjectorImpl
看看ViewInjectorImpl.registerInstance();
是如何初始化的:

非常清楚,一个单例模式,而ViewInjectorImpl
其实实现了ViewInjector
接口:

看看ViewInjector
接口:

该接口的说明很明了,就是可以不同对象类型进行视图注入,如View
,Avtivity
,以及ViewHolder
,fragment
,以满足各个场景的使用。
那我们进入到具体的Activity
进行分析吧:

可以看到MainActivity
继承了BaseActivity
,另外我们可以很明显的看到两种注解:@ContentView(id)
和@ViewInject(id)
,我们先看看ContentView
注解的源码:

@Target(ElementType.TYPE)
说明了该注解作用于类,接口或者枚举类型上。@Retention(RetentionPolicy.RUNTIME)
说明该注解会一直保留到JVM运行时。int Value()
说明可以注解参数的类型为int
类型;
那么@ContentView(R.layout.activity_main)
放入的就是布局activity_main
的id
值。
再来看看ViewInject
注解:

@Target(ElementType.FIELD)
说明该组件作用在成员变量上。@Retention(RetentionPolicy.RUNTIME)
说明该注解会保留到JVM运行时。int value();
说明注解参数类型为int
,而int parentId() default 0
说明可以填写一个父View的id,默认为0。
关于java
注解的基本使用,大家可以自行搜索。
现在我们知道了两个注解的作用:ContentView
注解是用来注入主布局界面的,而ViewInject
注解是用来注入具体控件的。
那么当MainActivity
回调onCreate
方法时,因为继承了BaseActivity
,所以自然就走到BaseActivity
的onCreate
方法:

那么接下来我们看看这个x.view().inject(this);
中的inject(this)
实现方法吧:

先获取了传入Activity
的Class
对象,然后将这个Class
作为参数传入findContentView(handlerType)
方法,从名字就可以看出该方法肯定是获取ContentView
的注解对象的:

该方法也是比较简单的,首先判断了 thisCls
是不是null
,或者是不是非法的Class
,看下IGNORED
:

这里看到IGNORED
是一个HashSet
保存了一些需要忽略的Class
对象。
通过检测后ContentView contentView = thisCls.getAnnotation(ContentView.class);
这句代码其实就是获取thisCls
上的注解ContentView
类,这里就是MainActivity
上的ContentView
注解。
如果获取的ContentView
为null
就继续在thisCls
的父类中获取。
这样我们分析完了findContentView(handlerType)
方法,作用就是获取传入类或父类上的注解ContentView
类。
我们继续回到inject()
方法,获取到ContentView
注解后,如果不为null
那么就通过int viewId = contentView.value();
获取注解中填写的id
值,也就是R.layout.activity_main
的值,然后

之后就是通过反射获取MainActivity
上的setContentView
方法,然后再反射调用该方法,将布局id值R.layout.activity_main
设置上去,这样就完成了MainActivity
布局的设置,基本原理就是通过注解+反射,还是比较简单的。
最后一句代码:

首先我们看看方法中的第三个参数是个ViewFinder
对象,将MainActivity
通过构造传递进去了。
先看看这个ViewFinder
类的内容:

该类的主要作用就是用于获取绑定的View
对象,就是将View
和Activity
的findViewById
方法进行封装,先大致了解下。
然后再返回injectObject()
方法,该方法较长,一部分一部分的贴出:

首先还是检测是否是合法的类,然后:

这里进行递归调用,然后是重点:

146行是获取所有声明的字段,这里我们就是MainActivity
中的字段了,然后开始循环。
150-157行是检测字段是不是合法的类型,如果合法才能继续。
159行就是获取字段上的ViewInject
注解类。
162行就是如果获取到的ViewInject
类不为null
,就将ViewInject
注解中填写的view
id和父view
id作为参数传递给finder
类来获取绑定的View
对象,回顾下MainActivity
中的字段:

可以看到只写了view
的id,并没有写父view
的id,那么父view
的id就是默认值0
了。
明白了再看看ViewFinder
类中:

36-38行就是说如果pid
大于0
,那么就获取父 view
对象,看看findViewById()
方法:

这里就是封装了findViewById
方法,适用于View
对象或者Activity
,这里我们是Activity
。
继续看40-45行,因为我们没有写pid
所以代码执行44行,这样我们就获取到了绑定的View
对象了。
这样我们再回到ViewInjectorImpl
类的injectObject(...)
方法:

这里就很清楚了,如果获取的View
对象不为null
,那么通过反射调用,将View
对象设置到field
上,这样就完成了一个视图控件的绑定,过程并不是很复杂。
原文链接:http://www.jianshu.com/p/7791f3b8c234
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
xUtils3源码分析(一):view的绑定的更多相关文章
- Android事件分发机制浅谈(三)--源码分析(View篇)
写事件分发源码分析的时候很纠结,网上的许多博文都是先分析的View,后分析ViewGroup.因为我一开始理解的时候是按我的流程图往下走的,感觉方向很对,单是具体分析的时候总是磕磕绊绊的,老要跳到Vi ...
- springMVC源码分析--视图View(一)
之前的博客springMVC源码分析--HttpMessageConverter数据转化(一)中我们已经介绍了数据返回值的处理,在博客springMVC源码分析--ViewResolver视图解析器( ...
- Android应用层View绘制流程与源码分析
1 背景 还记得前面<Android应用setContentView与LayoutInflater加载解析机制源码分析>这篇文章吗?我们有分析到Activity中界面加载显示的基本流程原 ...
- jQuery源码分析系列
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...
- jquery2源码分析系列
学习jquery的源码对于提高前端的能力很有帮助,下面的系列是我在网上看到的对jquery2的源码的分析.等有时间了好好研究下.我们知道jquery2开始就不支持IE6-8了,从jquery2的源码中 ...
- [转]jQuery源码分析系列
文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...
- Android源码分析—深入认识AsyncTask内部机制
本文转载http://blog.csdn.net/singwhatiwanna/article/details/17596225该博主博文,谢谢该博主提供的好文章! 前言 什么是AsyncTask,相 ...
- springMVC源码分析--页面跳转RedirectView(三)
之前两篇博客springMVC源码分析--视图View(一)和springMVC源码分析--视图AbstractView和InternalResourceView(二)中我们已经简单的介绍了View相 ...
- springMVC源码分析--视图AbstractView和InternalResourceView(二)
上一篇博客springMVC源码分析--视图View(一)中我们介绍了简单介绍了View的结构实现及运行流程,接下来我们介绍一下View的实现类做的处理操作. AbstractView实现了rende ...
随机推荐
- BZOJ 2572 高速公路
Description Y901高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这条高速公路上设立了许多收费站.Y901高速公路是一条由N-1段路以及N个收 ...
- Spring MVC 教程,快速入门,深入分析(转载)
作者:赵磊 博客:http://elf8848.iteye.com 下载: Spring的官方下载网址是:http://www.springsource.org/download (本文使用是的 ...
- XML CDATA
/* <![CDATA[ */var mv_dynamic_to_top = {"text":"To Top","version":& ...
- Borg Maze poj 3026
Description The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of ...
- ORACLE和MONGODB,必须也得进入。
先在WIN下面操作一下. 参考的是<MONGODB权威指南>
- Hibernate中的事务隔离
在我们的项目中,老发现程序报告sesssion is closed或者因数据已经被其他事务修改而导致当前事务无法提交,由于系统的运行用户最多也就几十个人,所以考虑使用严格的事务隔离来防止这种类型的问题 ...
- Paths on a Grid
http://poj.org/problem?id=1942 题意:一个n*m的格子,从左下角走到右上角有多少种走法,规定只能向上或向右走: 思路:解法挺水的,高中学组合数的时候老师给讲过:求C[m+ ...
- BZOJ 1071 [SCOI2007]组队
1071: [SCOI2007]组队 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1330 Solved: 417[Submit][Status][ ...
- POJ-Common Substrings(后缀数组-长度不小于 k 的公共子串的个数)
题意: 长度不小于 k 的公共子串的个数 分析: 基本思路是计算 A 的所有后缀和 B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于 k 的部分全部加起来. 先将两个字符串连起来,中间 ...
- 字符串(后缀自动机):COGS 2399. 循环同构
这道题直接看代码吧. #include <iostream> #include <cstring> #include <cstdio> using namespac ...