Android-逆向分析ButterKnife框架

好了,言归正传。

这一篇文章,我们不谈ButterKnife的基本使用,只谈如何通过JavaSe的技术,思考并分析ButterKnife这一Android开发界内排行前十的注解框架。

唯物主义辩证法认为,世界上一切事物都是具有普遍的联系我们首先从ButterKnife的使用步骤开始,倒推分析该框架使用了什么样的技术,然后自己写一个简单的ButterKnife小框架。

在正式写这篇博客之前,需要对反射以及注解(JavaSe技术)有一个初步的认识,就算不了解的也没有关系,笔者也提供了两篇博客供大家学习参考,点击这里了解反射点击这里了解注解 ,(这两篇也是笔者一字一字码出来的,望各位大兄弟不吝star)只需要花个十多分钟认真细心的看,反射和注解都不是很大的问题。接下来的东西还是很需要这两篇博客中使用到的基础。

说起ButterKnife(黄油刀),大家肯定会想到,哇,这个是用来简化findViewById以及快速实现点击事件等等一个深受大家好评的框架、没错,下图就是大家熟悉的写法


Android-逆向分析ButterKnife框架
butterKnife常用写法

熟悉注解的同学,可能一眼就看出,咦,这个@BindView以及@OnClick不就是两个注解吗?没错,的确是,而且,这个注解的类型是int值,因为里面是具体的View ID。了解这种情况后,就有了如下代码:首先,我们先写找控件的注解


Android-逆向分析ButterKnife框架
自定义控件注解

步骤1:

在使用ButterKnife注解之前,我们需要bind(Activty),

所以,我们就按照那种写法,先声明一个ButterKnife类,里面有个bind方法,参数是Activty

步骤2:

A:既然从外部传入了这个Activity,那么,我们就可以通过暴力反射获取该Activity上所有的成员变量,这里返回的是字段数组,

B:(因为是数组,所以需通过迭代器遍历获取每一个字段) 拿到成员变量之后,继续通过暴力反射其变量上的自定义注解  就  可以获取注解上的值(核心逻辑)

C:接着,我们既然通过B步骤已经获取到注解上的值(也就是控件的ID),那么就可以通过findViewByid去获取具体的View控件

D:最后,在通过反射将C步骤获取到的控件, 将其控件赋值给变量


Android-逆向分析ButterKnife框架
步骤1


Android-逆向分析ButterKnife框架
步骤2:模仿bindView逻辑


最后,为了测试这种写法能否达到预期的效果,我写了一个Demo,经测试,效果如图:


Android-逆向分析ButterKnife框架
测试用到的Xml
Android-逆向分析ButterKnife框架
没有findViewById依旧可以获取到属性值

经测试,myTextViewOne,myTextViewTwo这两个控件,我没有findViewById, 依旧可以获取到TextView上的值,所以,这个小功能经测试是可行的,

类似的,还有一个自定义注解点击事件,

依旧可以按照上面的写法,先写一个OnClick的自定义注解,如下图


Android-逆向分析ButterKnife框架
自定义点击事件注解

这里需要注意的是,

我们的点击事件的逻辑,是写在方法上的,所以,需要定义注解的使用范围是在方法上 也就是 @Target(ElementType.METHOD)

接下来的步骤,和上面的bindview 步骤差不多,

(暴力反射---获取注解的值----通过该值找到控件---对控件进行点击监听---反射调用使用了注解的方法),

这里直接上图


Android-逆向分析ButterKnife框架
自定义点击注解

接下来,我们写代码测试该注解:


Android-逆向分析ButterKnife框架
测试点击注解

经测试,这个功能是完全可以使用的,

这样,一个简单而不简约的迷你型ButterKnife框架就写好了。

最后总结:

1:自定义注解绑定的是具体的控件,也就是int值,根据自定义注解去定义这个int属性值

2:在使用了该自定义注解后的控件,通过暴力反射获取字段在根据其字段拿到具体的注解属性值

3:根据拿到具体的属性值,在做进一步的操作

4:当然,要是做到真正的ButterKnife框架还是有一些差距。但是我们这里只做简单的技术分析

最后,千里之行、始于足下,加油!

源码,(直接看图就可以了吧)附github地址

项目地址

    如果这篇文章对你有帮助,希望各位看官留下宝贵的star,谢谢。

Ps:著作权归作者所有,转载请注明作者, 商业转载请联系作者获得授权,非商业转载请注明出处(开头或结尾请添加转载出处,添加原文url地址),文章请勿滥用,也希望大家尊重笔者的劳动成果,谢谢。