apt不再神秘
apt是编译期还是运行期生效的?
apt和aspectj有什么区别?
Android Databinding、Butterknife、Dagger2、ARouter你也许在用,它们是怎么实现的呢?
看过本文,也许你也能写出一个Dagger2,你知道它并没有用到哪些你不能理解的黑科技。
一、apt原理
什么是apt?
apt就是javac对外开放的一个插件,使javac在编译期间根据注解(Annotation)获取相关数据 。

更多Android相关流程图请移步andych008/flow_chart)
apt能干什么?
通过这个插件,多数情况下我们会在编译过程中生成java文件。最终我们通过工具类调用这些生成的代码(有些时候工具类通过反射自动完成这一步),完成一些重复性的工作。
比如:
- Android Databinding绑定view
activity_main.xml会生成ActivityMainBinding.java。调用工具类的
android.databinding.DataBindingUtil.setContentView(this, R.layout.activity_main);完成数据绑定 - Butterknife绑定view
MainActivity会生成MainActivity$$ViewBinder<T extends MainActivity> implements ViewBinder<T>调用工具类的
ButterKnife.bind(this);完成绑定 - Dagger2注入变量
BackCamara的构造方法加注解@Inject public BackCamera() {}生成BackCamera_FactoryPhone的成员加注解@Inject public BackCamera mCamera;生成Phone_MembersInjectorComponent接口加注解@Component public interface PhoneComponent生成DaggerPhoneComponent调用工具类的
DaggerPhoneComponent.create().inject(this);完成注入。 - ARouter生成路由表
apt不能干什么?
apt不能修改已有代码的执行流程,如果要实现类似“日志打点”等在原代码的基础上插入一些功能,一般需要通过aspectj来实现。这类功能是在编译后期(javac之后)修改字节码文件来实现。
apt怎么参与到javac的编译过程的?
apt与javac约定在META-INF/services/javax.annotation.processing.Processor文件中注册apt插件。
知道了apt的工作原理,再学习它的使用,会是一件很easy的事件情。
apt的使用,见最下面的 Demo源码
二、开发相关
apt为什么得远程调试
https://www.jianshu.com/p/cb02566337ee./gradlew --no-daemon -Dorg.gradle.debug=true :app:clean :app:compileDebugJavaWithJavac
因为apt代码执行在编译器所在的进程
向apt程序传参
1 | @SupportedOptions({ "debug" }) |
1 | android { |
三、扩展阅读1
很多时候,我们写apt插件,都会引入@AutoService和JavaPoet来提升开发效率。
@AutoService的工作原理
@AutoService本质上也是一个apt插件,我们的apt插件通过注解的方式@AutoService(javax.annotation.processing.Processor.class)注册到@AutoService里。@AutoService在编译期为我们的apt插件生成META-INF/services/javax.annotation.processing.Processor文件,帮助我们完成注册。- 因为javac对注解处理是循环解析、编译,所以
@AutoService的方式是可行的。
JavaPoet的作用
JavaPoet的作用就是帮助我们生成java源文件,核心类CodeWriter.java
比如Butterknife生成MainActivity$$ViewBinder,使用到了JavaPoet,否则只能通过拼接字符串的方式(如下面Demo源码的master分支)。不但提高了开发效率,而且代码的可读性更好,见ButterKnifeProcessor.java。
Demo源码
mydev分支在master基础上引入@AutoService和JavaPoet。建议无基础的朋友,先学习master分支。在此先感谢master分支的作者LiMubai2017
四、扩展阅读2
和apt相关的知识,当然是aspectj和ASM了。当然还有gradle Transform Api。这些,以后再聊。