Butterknife source analysis
本文分析的源码为8.4.0
。
项目结构¶
butterknife
包含ButterKnife核心的Api,如ButterKnife。butterknife-annotations
包含了所有定义的注解。butterknife-compiler
包含了生成模板代码的代码。这里我们重点研究ButterKnife是如何生成模板代码以及在我们的类中是如何调用的。
核心类¶
ViewBinding
是一个接口,有两个直接的子类FieldViewBinding
和MethodViewBinding
。
FieldViewBinding
封装了使用@BindView
注解的Field的信息。
MethodViewBinding
封装了使用@OnClick
等注解注解的方法的信息。
注解@ListenerClass代表一个监听器的类,作用在如@OnClick等事件监听的注解上。
ViewBindings
封装了一个View的所有ViewBinding
。例如在SimpleActivity中有如下代码
R.id.hello
这个view对应的ViewBindings包含一个FieldViewBinding和两个MethodViewBinding。
BindingSet
可以看做是一个类里面所有所有Binding信息。同时还负责生成代码的逻辑。
ResourceBinding是一个接口,有两个实现类FieldResourceBinding和FieldDrawableBinding。
解析注解¶
知道各个类的作用之后,下一步工作就是了解如何解析这些标注了注解的字段和方法的信息,并封装成类。
ButterKnife解析这些信息的类为ButterKnifeProcessor
,解析的工作由findAndParseTargets
方法完成。
findAndParseTargets
获取不同注解对应的Element,然后调用对应的parse方法来解析。
解析@BindView¶
parseBindView
解析@BindView
注解的Element。
isInaccessibleViaGeneratedCode
方法用于通过修饰符来判断字段是否能够被生成的代码访问。由于ButterKnife的原理是通过辅助类来完成findViewById的操作,所以必须引用原来的的字段,因此不能设置为private
解析方法注解¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
|
解析资源绑定¶
解析资源的代码基本都差不多。这里只给出parseResourceString的源码和注释。
设置parentBinding¶
在findAndParseTargets最后几行代码的作用是为解析出来的BindingSet.Builder设置parentBinding
生成代码¶
生成代码主要由BindingSet的brewJava方法完成。
target.title = Utils.findRequiredViewAsType(source, R.id.title, "field 'title'", TextView.class);
。
调用辅助方法¶
我们在类中通过调用ButterKnife的bind方法来调用辅助类的。