【Android】如何实现ButterKnife
来源:互联网 发布:linux网络基础 编辑:程序博客网 时间:2024/05/20 06:40
如何实现ButterKnife
ButterKnife的原理简述
示例代码ButterKnifeProcedure
Pluggable Annotation Processing
注解处理器
Java5 中叫APT(Annotation Processing Tool),在Java6开始,规范化为 Pluggable Annotation Processing。
第一步(收集信息)
找到所有被注解的属性或者方法,将所有的信息收集到对应的“类数据集”中。
第二步(生成源文件)
根据每一个“类数据集”,生成对应的java源文件。由于这些文件并不是在运行时生成的,因此也无需动态编译,注解处理器运行完成之后,
编译器会处理所有的编译流程。
第三步(动态注入)
运行时动态注入,即用户常规调用的 ButterKnife.bind(activity)
这一步为了避免蹩脚的调用,使用了运行时反射,但是作者对每一个类进行了缓存,因此,不会对执行效率产生多大影响。
注
在最新的 ButterKnife 源码(2015.06.08)中,ButterKnife已经重构了部分方法:
ButterKnife#inject -> ButterKnife#bind
@InjectView -> @FindView
等等,具体变化可以去看官方文档,本文档后续代码使用最新版本代码演示。
极简实现演示
演示代码说明
- 示例代码由 ButterKnife 简化而来,部分定义和实现有删改,只能绑定 Activity 中的 View 字段
- 为了避免引入Android平台,但是又需要更直观,所以mock了android的两个类,Activity 和 View
- 为了避免使用 Pluggable Annotation Processing 过程中的jar包要求,以及波及不必要的java文件,请使用命令行运行演示,直接运行 ./run.sh 即可查看结果
- 保证 CLASSPATH 中含有tools.jar
第一步(收集信息)
- 在每一个类中找到所有被 FindView 注解的字段
每一个需要绑定的字段信息都保存为一个 FieldViewBinding 对象,比如:
@FindView(100)View vView1;得到:new FieldViewBinding(vView1, android.view.View, 100)
将字段分类,获取每一个类的“类数据集”BindingClass,比如, MainActivity 对应的 “类数据集” 如下:
MainActivity: List<FieldViewBinding> fieldViewBindings = new ArrayList<FieldViewBinding>(); fieldViewBindings.add(new FieldViewBinding(vView1, android.view.View, 100)) fieldViewBindings.add(new FieldViewBinding(vView2, android.view.View, 200))
第二步(生成 Bind 工具类源文件)
为了便于在反射时容易实例化生成的类,每一个生成的类都实现了一个 ActivityBinder 接口,因此,根据 MainActivity “类数据集”生成的文件如下:
package sample;import android.view.View;import android.app.Activity;import butterknife.ButterKnife.ActivityBinder;public class MainActivity$$ViewBinder implements ActivityBinder<sample.MainActivity> { @Override public void bind(sample.MainActivity target) { View view; view = target.findViewById(100); target.vView1 = view; //这里要求 vView1 的访问权限为 package 级别 view = target.findViewById(200); target.vView2 = view; }}
第三步(动态注入)
我们在 MainActivity 中调用 ButterKnife#bind,第一件事就是找到对应生成的 Bind 工具类,这里遵循命名规则(在对应类后增加 $$ViewBinder 后缀),直接使用动态加载并实例化:
Class<?> activityBindingClass = Class.forName(targetClass.getName() + ButterKnifeProcessor.SUFFIX);activityBinder = (ActivityBinder) activityBindingClass.newInstance();
获得相应的 ActivityBinder 之后,使用 ActivityBinder#bind 进行绑定,与手动调用 findViewById 效果相同
运行
运行:
ButterKnifeProcedure/src$ ./run.sh
结果:
mainActivity.vView1.id = 100mainActivity.vView2.id = 200
Android分享 Q群:315658668
- 【Android】如何实现ButterKnife
- 【Android】如何实现ButterKnife
- Android实现ButterKnife
- Android ButterKnife 的实现思路
- AndroidStudio ButterKnife+Android ButterKnife Zelezny实现高效率布局绑定
- Android Studio 中如何引入ButterKnife插件
- android注解与反射、ButterKnife实现
- android ButterKnife
- Android ButterKnife
- Android ButterKnife
- Android Butterknife
- Android Butterknife
- ButterKnife + ButterKnife Zelezny(Android Studio)
- Android Studio 如何在 Kotlin 中使用 ButterKnife
- Android实现文章+评论(MVP,RxJava,Dagger2,ButterKnife)
- Android MVP 实现。基于Dagger2 + RxJava + Retrofit2 + Realm + ButterKnife + EventBus
- 【Android 进阶】ButterKnife+Retrofit+Picasso+RecycleView 实现一个小案例
- 如何正确使用Butterknife
- Deep Learning for Beginners
- 力控调用Qrmaker实现二维码显示
- ASCII、Unicode、GBK和UTF-8
- 【Android】如何快速构建Android Demo
- 二维数组作为形参的参数传递问题
- 【Android】如何实现ButterKnife
- 用jQuery前,先看看jQuery库文件件导入没!
- 【笔记】 《js权威指南》- 第17章 事件处理 17.7 - 17.8
- Android APK瘦身之Android Studio Lint (代码审查)
- jQuery使用简单示例 validate 插件
- Machine Learning第八周笔记:K-Means和降维
- 探索Java interface和abstract类的秘密
- 【HDU 1165】【水题】Eddy's research II
- 蓝桥杯第四题,就是快排,学习懂了应该很简单