Butterknife源码分析

最后

如果觉得本文对你有帮助的话,不妨给我点个赞,关注一下吧!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

Butterknife源码分析

https://www.wanandroid.com/article/query?k=butterknife

Android主流三方库源码分析(七、深入理解ButterKnife源码)

1、Butterknife原理

===================

讲到butterknife的原理。这里不得不提一下一般这种注入框架都是运行时注解,即声明注解的生命周期为RUNTIME,然后在运行的时候通过反射完成注入,这种方式虽然简单,但是这种方式多多少少会有性能的损耗。那么有没有一种方法能解决这种性能的损耗呢?   没错,答案肯定是有的,那就是Butterknife用的APT(Annotation Processing Tool)编译时解析技术

注意:Butterknife是不使用反射的。

APT大概就是你声明的注解的生命周期为CLASS,然后继承AbstractProcessor类。继承这个类后,在编译的时候,编译器会扫描所有带有你要处理的注解的类,然后再调用AbstractProcessor的process方法,对注解进行处理,那么我们就可以在处理的时候,动态生成绑定事件或者控件的java代码,然后在运行的时候,直接调用bind方法完成绑定。

其实这种方式的好处是我们不用再一遍一遍地写findViewById和onClick了,这个框架在编译的时候帮我们自动生成了这些代码,然后在运行的时候调用就行了。

2、源码解析

======

版本:

//butterknife

implementation ‘com.jakewharton:butterknife:10.2.1’

annotationProcessor ‘com.jakewharton:butterknife-compiler:10.2.1’

拿到源码的第一步是从我们调用的地方来突破,那我们就来看看程序里面是怎样调用它的呢?

@BindView(R.id.btn100)

Button btn100;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

ButterKnife.bind(this);

}

@OnClick(R.id.btn100)

public void onViewClicked() {

}

我们直接就从 **ButterKnife.bind(this)**入手吧,点进来看看:

@NonNull @UiThread

public static Unbinder bind(@NonNull Activity target) {

View sourceView = target.getWindow().getDecorView();

return bind(target, sourceView);

}

根据activity得到DecorView,再传递到bind。

@NonNull @UiThread

public static Unbinder bind(@NonNull Object target, @NonNull View source) {

Class<?> targetClass = target.getClass();

if (debug) Log.d(TAG, "Looking up binding for " + targetClass.getName());

Constructor<? extends Unbinder> constructor =

findBindingConstructorForClass(targetClass);

if (constructor == null) {

return Unbinder.EMPTY;

}

//noinspection TryWithIdenticalCatches Resolves to API 19+ only type.

try {

return constructor.newInstance(target, source);

} catch (IllegalAccessException e) {

throw new RuntimeException("Unable to invoke " + constructor, e);

} catch (InstantiationException e) {

throw new RuntimeException("Unable to invoke " + constructor, e);

} catch (InvocationTargetException e) {

Throwable cause = e.getCause();

if (cause instanceof RuntimeException) {

throw (RuntimeException) cause;

}

if (cause instanceof Error) {

throw (Error) cause;

}

throw new RuntimeException(“Unable to create binding instance.”, cause);

}

}

言尽于此,完结

无论是一个初级的 coder,高级的程序员,还是顶级的系统架构师,应该都有深刻的领会到设计模式的重要性。

  • 第一,设计模式能让专业人之间交流方便,如下:

程序员A:这里我用了XXX设计模式

程序员B:那我大致了解你程序的设计思路了

  • 第二,易维护

项目经理:今天客户有这样一个需求…

程序员:明白了,这里我使用了XXX设计模式,所以改起来很快

  • 第三,设计模式是编程经验的总结

程序员A:B,你怎么想到要这样去构建你的代码

程序员B:在我学习了XXX设计模式之后,好像自然而然就感觉这样写能避免一些问题

  • 第四,学习设计模式并不是必须的

程序员A:B,你这段代码使用的是XXX设计模式对吗?

程序员B:不好意思,我没有学习过设计模式,但是我的经验告诉我是这样写的

image

从设计思想解读开源框架,一步一步到Spring、Spring5、SpringMVC、MyBatis等源码解读,我都已收集整理全套,篇幅有限,这块只是详细的解说了23种设计模式,整理的文件如下图一览无余!

image

搜集费时费力,能看到此处的都是真爱!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

片转存中…(img-hT3xhugR-1715815502167)]

搜集费时费力,能看到此处的都是真爱!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值