Butterknife源码分析(1)

Java高频面试专题合集解析:

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

更多Java架构进阶资料展示

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等

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

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

讲到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);

}

}

上面的代码里,获取到Constructor后,再运用反射生成实例,在实例里的findView操作就会被调用到。接下来看看如何获取到Constructor的。

@Nullable @CheckResult @UiThread

private static Constructor<? extends Unbinder> findBindingConstructorForClass(Class<?>

cls) {

Constructor<? extends Unbinder> bindingCtor = BINDINGS.get(cls);

if (bindingCtor != null || BINDINGS.containsKey(cls)) {

最后

针对以上面试题,小编已经把面试题+答案整理好了

最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo

最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo

最新大厂必问微服务面试题汇总:SpringCloud、Boot、Dubbo

面试专题

image

除了以上面试题+答案,小编同时还整理了微服务相关的实战文档也可以分享给大家学习

image

image

image

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

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

434364)]

[外链图片转存中…(img-CAnDpeZg-1715815434364)]

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值