ButterKnife(https://github.com/JakeWharton/butterknife)是一款android平台的依赖注入框架,通过该工具可以实现View、OnClickListener的注入,省去了findViewById、setOnClickListener的过程。使用方法如下:

通过@BindView注解实现findViewById的功能,完成View注入;通过@OnClick完成OnClickListener点击事件的注入,给ID对应的View设置点击事件和响应函数。关于注解的定义和解析可以参照这篇文章:Java注解。ButterKnife使用的就是编译时解析注解的技术,在编译时对注解进行解析,生成中间文件,在ButterKnife.bind时引用注解编译器生成的中间文件,完成依赖注入。

注解的定义

BindView注解定义

BindView注解定义中使用了元注解@Retention(CLASS)定义了该注解只保留到编译期间,运行时会丢弃;@Target(FIELD)表示该注解只能用在成员变量上面。

OnClick注解

OnClick注解中@Target(METHOD)表示该注解只能用于方法上;

ListenerClass

ListenerClass是一个@Target(ANNOTATION_TYPE)类型的注解,表示ListenerClass只能用在注解上;且@Retention(RUNTIME)表示该注解可以保留到JVM中,也就是运行时能够通过反射来获取。

注解的解析

下面对@BindView和@OnClick两种注解的解析进行讲解。编译时注解的解析:

编译时 Annotation 指 @Retention 为 CLASS 的 Annotation,由编译器自动解析。需要做的

a. 自定义类集成自 AbstractProcessor(编译器在编译时自动查找所有继承自 AbstractProcessor 的类,然后调用他们的 process 方法去处理)

  b. 重写其中的 process 函数

ButterKnife实现了ButterKnifeProcessor来进行编译时注解的解析:

ButterKnifeProcessor

ButterKnifeProcessor.process()函数如下:

ButterKnifeProcessor.process

process函数先调用findAndParseTargets生成bindingMap,然后通过binding.brewJava老生成Java文件。findAndParseTargets的实现如下(这里只关注@BindView和@OnClick):

findAndParseTargets

其中调用parseBindView对注解为@BindView的Field进行解析;findAndParseListener对@OnClick之类的Listener注解进行解析。parseBindView代码如下:

parseBindView

parseBindView的主要工作是创建了BindingSet.Builder。getOrCreateBindingBuilder()如下:

getOrCreateBindingBuilder

getOrCreateBindingBuilder内部调用了BindingSet.newBuilder。

BindingSet.newBuilder

newBuilder生成了Builder对象,Builder对象定义了生成的Java文件名、mView所属对象的类型等。Builder对象生产后,parseBindView就根据@BindView注解信息生成FieldViewBinding对象,之后调用了Builder.build()函数;@BindView的解析已经完成后,最后通过BindingSet.brewJava来生成中间文件。@BindView在生成文件对应了如下:

addViewBinding

生成的中间文件如下所示:

中间文件

可以看到,中间文件里完成了对Target中成员变量的注入。

那么中间文件又是在什么时候被调用的呢?答案就是ButterKnife.bind(this)

bind函数根据调用的类名查找其对应的className_ViewBinding的类名,然后反射调用其构造函数。

至此,ButterKnife的@BindView的运行流程就是这样。

ButterKnife源码解析相关推荐

  1. BAT高级架构师合力熬夜15天,肝出了这份PDF版《Android百大框架源码解析》,还不快快码住。。。

    前言 为什么要阅读源码? 现在中高级Android岗位面试中,对于各种框架的源码都会刨根问底,从而来判断应试者的业务能力边际所在.但是很多开发者习惯直接搬运,对各种框架的源码都没有过深入研究,在面试时 ...

  2. Android之DiskLruCache源码解析

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/73863258 本文出自:[顾林海的博客] 个人开发的微信小程序,目前功 ...

  3. 深入理解ButterKnife源码并掌握原理(三)

    上两篇我们分析完了处理器的process方法的findAndParseTargets方法来获取了一个集合,该集合包含了你使用注解的类的TypeElement和这个类中的注解的实例BindingClas ...

  4. 深入理解ButterKnife源码并掌握原理(二)

    好,我们接着parseBindView的步骤3 ,忘记了在哪里了,咦. 可以看下上一篇,哈哈. 步骤3 BindingClass bindingClass = targetClassMap.get(e ...

  5. 深入理解ButterKnife源码并掌握原理(一)

    前言 话说在android这座大山里,有一座庙(方块公司-square),庙里住着一个神-jake(我是这么叫的嘻嘻). 不要小看这个小jake,这个神可是为android应用开发们提供了强有力的帮助 ...

  6. 牛掰!阿里P7大佬爆肝半个月,把安卓源码解析编成了508页的PDF

    前言 有一部分人拥有非常宝贵的精神,因为他们的坚持和贡献,我们中国的技术才一步步前进,一步步走向世界.Android行业一直在进步和发展,也正是因为这些人坚持总结经验和分享. 比如有位阿里P7大牛,每 ...

  7. 谷歌BERT预训练源码解析(二):模型构建

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...

  8. 谷歌BERT预训练源码解析(三):训练过程

    目录 前言 源码解析 主函数 自定义模型 遮蔽词预测 下一句预测 规范化数据集 前言 本部分介绍BERT训练过程,BERT模型训练过程是在自己的TPU上进行的,这部分我没做过研究所以不做深入探讨.BE ...

  9. 谷歌BERT预训练源码解析(一):训练数据生成

    目录 预训练源码结构简介 输入输出 源码解析 参数 主函数 创建训练实例 下一句预测&实例生成 随机遮蔽 输出 结果一览 预训练源码结构简介 关于BERT,简单来说,它是一个基于Transfo ...

最新文章

  1. web服务器错误配置文件,web服务器http配置文件
  2. Android 导出traces.txt 遇到的坑
  3. ubuntu 查看串口,设置串口权限
  4. onedrive目录PHP源码,另一个OneDrive目录索引应用 OLAINDEX
  5. commons-lang3工具类学习(三)
  6. JavaScript判断设备类型加载对应网页并设置两端通用事件
  7. BCVP开发者社区2022专属周边第一弹
  8. CF1446F-Line Distance【计算几何,树状数组,二分】
  9. Hibernate自动提交命令强制MySQL在过多的磁盘I / O中运行
  10. 线段树区改区查标记永久化板子
  11. Linux C函数之文件及目录函数
  12. System V消息队列
  13. asp.net中前台javascript与c#函数相互调方法
  14. java看视频可以学会吗,看it教程视频自学Java编程可以学会吗?
  15. WIFI和蓝牙无线模块的应用小结
  16. HTML前端代码分析(查看网站黑链的几种方法)暗链是什么意思
  17. 【脑图制作】万彩脑图大师教程 | 怎么制作思维导图
  18. ansys添加力矩_ANSYS中加载力矩
  19. python医院体检预约系统django548
  20. android4.4 获取符合默认短信应用要求的短信应用包名(改进篇)

热门文章

  1. SAP MM 如何看一个Inbound Delivery单据相关的IDoc?
  2. AAAI 2020 | 自动化所:基于对抗视觉特征残差的零样本学习方法
  3. 在SAP PI中建立场景
  4. 科学家王海峰:从百度十篇论文入选ACL 2019说起
  5. 放弃手工标记数据吧!斯坦福大学开源弱监督框架
  6. SAP MM MI01事务代码里的批次确定
  7. 福利丨吴恩达机器学习新书免费领!
  8. 干货丨科普丨大牛的《深度学习》笔记,Deep Learning速成教程
  9. Python 之 matplotlib (七)Scatter
  10. numpy如何生成随机数