ButterKnife省略findViewById的原理

  • ButterKnife是JakeWhartorn及其他程序员开发的第三方库。
  • ButterKnife源码地址:ButterKnife.java

ButterKnife省略findViewById和setOnClickListener的大致原理是什么?

 插件自动补全Java注解BindView(R.id.tvName),和ButterKnife.bind(this);这行代码。
 项目在编译时,会读取所有java文件信息,并调用annotationProcessor,也就是ButterKnifeProcessor,来读取MainActivity的类信息,并通过javaPoet生成MainActivity_ViewBinding.java这个类文件。在这个类的构造方法中,包含了findViewById和setOnClickListener的逻辑。
  程序执行到onCreate()中的ButterKnife.bind(this)这行代码时,会反射生成一个MainActivity_ViewBinding类的对象vb,也就调用了它的构造方法,从而避免了开发者手写findViewById和setOnClickListener。

ButterKnifeProcessor具体什么时候被调用?

  在编译时,java编译器(javac)会去META-INF中查找实现了的AbstractProcessor的子类,并且调用该类的process函数,最终生成.java文件。其实就像activity需要注册一样,就是要到META-INF注册 ,javac才知道要给你调用哪个类来处理注解。参考:Android APT工作原理(annotationProcessor)

怎么自动生成MainActivity_ViewBinding.java的?

 JavaPoet这个库,可以自动生成.java代码。生成MainAcitivity_ViewBinding.java的逻辑在ButterKnifeProcessor中,详见JavaPoet - 优雅地生成代码

TextView对象是如何生成的?

ButterKnife.bind(this);这行代码传入了Activity对象,根据Activity实例可以获取DecorView,通过decorView.findViewById(id)获取TextView对象。

findViewById方法需要一个参数id,如何获取这个id?

 根据Activity实例,反射获取每一个属性Field,再反射获取Field的注解:BindView bindView = field.getAnnotation(BindView.class);,在从注解里面获取具体的id值:int id = bindView.value();。这个过程,这篇文章讲的通俗易懂:Butterknife之从反射到注解
 在源码中,获取id的逻辑在ButterKnifeProcessor的parseBindView()方法中:

    // Assemble information on the field.
    int id = element.getAnnotation(BindView.class).value();

 直接贴出源码位置:ButterKnifeProcessor:495

8.8.1版本源码分析:ButterKnife原理解析看这篇文章就够了

猜你喜欢

转载自blog.csdn.net/zhangjin1120/article/details/120943474
今日推荐