源码地址:https://github.com/JakeWharton/butterknife.git
JakeWharton大神主页:https://github.com/JakeWharton
神作: butterknife RxAndroid RxBinding okhttp okio retrofit(后面3个都是Square的)
Jake大神喜欢以刀命名自己的项目,如butterknife(黄油刀),Dagger(匕首),还有Scalpel(解剖刀),一个很炫酷的查看View Tree的小工具。以刀命名自己的项目可能他觉得一个好的项目应该像刀一样犀利吧。
Rxjava:链式调用序列实现基于事件流的异步编程库,核心思想是把一切重复化的(尤其多重嵌套异步)调用逻辑转换为基于事件(数据)流传递过程的观察者模式。优势在于便捷安全的多种线程切换策略,构建异步事件逻辑,通过事件流(数据流)的切面分解实现逻辑平面化,解除多重异步回调的深层嵌套.
RxAndroid:RxJava针对Android的定制版本.
RxBinding:RxJava封装的View事件处理,可以实现数据层与View层的绑定,当数据发生变化,View会自动更新UI
okio:是对java.io和java.nio的补充,以更方便的访问、存储及处理数据。
retrofit:Retrofit是Square开发的一个用于网络请求的开源库,内部封装了okhttp,并且和RxAndroid完美的兼容,使得Android的开发效率增加不少的同时也使代码变得清晰易读。使用请求参数注解。
回到ButterKnife上来。
ButterKnife是一个用注解的方式生成公式化的代码将Android view的域和方法绑定一起的库。
用法大家都知道了,@Bind,@BindBool, @BindColor, @BindDimen, @BindDrawable, @BindInt, @BindString使用这些注解与资源id进行绑定。以前的版本里有用过
InjectXX和FindXX的,新版本采用BindXX。
例子: 在Activity中,
@Bind(R.id.title) TextView title;
@BindString(R.string.title) String title;
@BindDrawable(R.drawable.graphic) Drawable graphic;
当然在非Activity中,比如Fragment的和adapter里也可以用,不过调用时要多加一个root view参数。
Fragegment使用时记得同时继承onDestroyView,并在其中将ButterKnife.reset.
View view = inflater.inflate(R.layout.fancy_fragment, container,false);
7 ButterKnife.inject(this, view);
等等这些。。。这些简单的使用。
我们今天主要是来共同学习一下深层次的用法和它的实现原理。有疑问随时都可以提出来。
@OnClick(R.id.submit)
public voidsubmit(View view) {
}
或者
@OnClick({ R.id.door1, R.id.door2, R.id.door3 })多个id绑定到一个方法里
public voidsubmit(View view) {
}
在绑定取消的时候调用unbind方法
ButterKnife.unbind(this);
接下里共同探讨ButterKnife的注解方式。
ButterKnife采用的是Java Annotation Processing技术,Annotation Processing是javac中用于编译时扫描和解析Java注解的工具,它的任务就是读入java源代码,解析注解然后生成新的java代码。生成的java代码最后北编译成java字节码。
附java编译流程图:
来看下工程结构,是分下面3块:
butterknife(负责工程的主要逻辑调用入口)
butterknife-annotations(负责所有注解的自定义文件,实现了BindXX方法)
butterknife-compiler(负责在编译时解析Annotations)
很显然最重要的是butterknife-compiler。它在检测到含有注解的类时,会生成 类名_ViewBinding类,位置是在具体
生成了这个文件后,我们看下它是怎么用的。ButterKnife#bind,主要就是找到这个生成类并拿到DecorView,
Class<?> bindingClass = Class.forName(clsName + "_ViewBinding");
bindingCtor = (Constructor<? extends Unbinder>) bindingClass.getConstructor(cls, View.class);
进入生成类看一下, view = Utils.findRequiredView(source, R.id.text1, "method ‘click'");
就是帮你做findViewById的操作了。
最主要的就是annotation processor, 我们可以尝试一下自定义注解。