首页 > 代码库 > Butterknife实现原理

Butterknife实现原理

 

                        Butterknife实现原理

 一、简介

    1、特点

       低版本不使用APT(Annotation Processing Tool)编译时解析技术,使用时仅添加依赖。在Butterknife8.0版本及以上使用APT。

      一般注入框架都是运行时注解,即声明注解的生命周期为RUNTIME,然后在运行的时候通过反射完成注入,方式虽然简单,但会有

    性能的损耗。我们不用再重复写findViewById和onClick,框架在编译的时候帮我们自动生成了这些代码,在运行时调用。

  二、源码分析

     2.1  步骤

        1)在onCreate()中写  ButterKnife.bind(this);和ButterKnife.setDebug(true);bind方法主要是拿到我们绑定的Activity的Class,

      然后找到这个Class的ViewBinder,最后调用ViewBinder的bind()方法。

        2)打开findViewBinderForClass()先保存了Class为key,Class$$ViewBinder为Value的一个LinkedHashMap,主要是做缓存,提高

      下次再来bind的性能。

        3)clsName 是我们要传入绑定的Activity类名,相当于拿到了Activity$$ViewBinder。它是Activity的一个内部类,即AbstractProcessor

    编译时生成的类。用反射反射了一个viewBinder 实例。此方法中用linkhashMap做了缓存,把刚刚反射的viewBinder作为value,Class作为

    key加到LinkedHashMap,下次再bind此类时,直接取出来用,提升性能。

        4)返回刚刚的bind方法,我们拿到了这个Activity的viewBinder,然后调用它的bind方法。

    2.2  以TextView测试的例子

        准备好布局,写上id,ButterKnife的bind()    

        使用jd-jui等源码查看工具查看所写项目的workspace;路径为

      项目名/app/build/intermediates/classes/debug/主Activity所在的包名下MainActivity$$ViewBinder此class文件

    实现原理

      1)在bind方法中,最后调用了ViewBinder的bind方法,参数:paramFinder是一个Finder,在Activity、Fragment和Adapter等

    不同地方都可用butterknife。paramT和paramObject都是我们要绑定的Activity类。

      2)返回上面的ViewBinder代码,先调用Finder的findRequiredView(),经过处理就是调用了findView方法,拿到相应的view,

    然后再赋值给paramT.textView,paramT就是那个要绑定的Activity。

      3)通过 paramT.textView 调用,说明了Activity中不能把TextView设置为private,不然会报错。可以用反射来拿到textView的。

      4)最后setOnClickListener,DebouncingOnClickListener这个Listener其实也是实现了View.OnClickListener 方法,然后在

    OnClick里面调用了doClick方法。

   *  Butterknife到底是怎样在编译的时候生成代码的? 我们来看一下它的ButterKnifeProcessor类:

      Init方法: ProcessingEnviroment参数提供很多有用的工具类Elements, Types和Filer。

        Types是用来处理TypeMirror的工具类。

        Filer用来创建生成辅助文件。

        ElementUtils是ButterKnifeProcessor运行时,会扫描所有的Java源文件,然后每一个Java源文件的每一个部分都是一个Element,

      比如一个包、类或者方法。

         getSupportedAnnotationTypes()方法主要是指定ButterknifeProcessor是注册给哪些注解的。把Class文件加到那个

      LinkedHashSet里面,然后再把LISTENERS也全部加进去。

      其实整个类最重要的是process方法:作用主要是扫描、评估和处理我们程序中的注解,然后生成Java文件。也就是前面说的ViewBinder。

    首先一进这个函数就调用了findAndParseTargets方法。其后的方法使用RXJava。

 

Butterknife实现原理