(对应自己练习时的项目为testAnnotation,这里面有踩过的坑)
1 router支持注解,使用方便(注解在编译期处理,不影响运行时的性能)
注解: 仅仅是元数据,和逻辑无关,所以当你查看注解类时,会发现里面没有任何逻辑处理
注解的作用
格式检查:告诉编译器信息,比如被@Override标记的方法如果不是父类的某个方法,IDE会报错;
减少配置:运行时动态处理,得到注解信息,实现代替配置文件的功能;
减少重复工作:比如第三方框架xUtils,通过注解@ViewInject减少对findViewById的调用,类似的还有(JUnit、ActiveAndroid等);
注解:
讲解自定义注解比较好的文章https://www.jianshu.com/p/07ef8ba80562
2 链接调用
3 不仅支持注解activity 还支持注解fragment
frameworkcompile的RouterProcessor的学习
注解处理器:是javac的一个工具,它用来在编译时扫描和处理注解,你可以自定义注解,并且注册相应的注解处理器,通过扫描注解,使用javaPoet生成一个新的java文件,这个java文件也和其他手动编写的源代码一样被javac编译
1 定义编译时的注解。
注解的类型
注意: source类型的注解主要是@IntDef类型的元注解,在编写代码时就有
2 定义注解处理器,新建一个java工程,必须是java工程,不然找不到javax包下的相关资源
init()方法会被注解处理工具调用,并传入processingEviroment参数,它提供了很多有用的工具类,elements,types,filer,
它是用来提供给processor用来访问工具框架的环境
对于 getSupportedAnnotationTypes() 方法标明了这个注解处理器要处理哪些注解,返回的是一个Set 值,说明一个注解处理器可以处理多个注解。除了在这个方法中指定要处理的注解外,还可以通过注解的方式来指定(SourceVersion也一样
//指定该注解处理器可以解决的类型,需要完整的包名+类名
@SupportedAnnotationTypes("com.jifen.framework.annotation.Router")
//指定编译的JDK版本
@SupportedSourceVersion(SourceVersion.RELEASE_7)
https://juejin.im/entry/5a31e280f265da43305e7a42遇到一个错误,我在注解中的Log打不出来,坑了我好几个小时
最后碰到的,在引用注解的module中加入
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath true
}
}
3 不用手动创建Resources/META-INF/.....去声明注解处理器,直接引入一个包'com.google.auto.service:auto-service:1.0-rc2' 。 然后在自定义的Processor里面使用@autoservice(processor.class)
APT:
大体来讲它有两个作用:
能在编译时期去依赖注解处理器并进行工作,但在生成 APK 时不会包含任何遗留的东西
能够辅助 Android Studio 在项目的对应目录中存放注解处理器在编译期间生成的文件
坑: 每天都能遇到稀奇古怪的问题,在工程中引入apt的插件,然后在需要引入processor工程的地方https://blog.csdn.net/qqDa6/article/details/78681282(详情见此链接)
讲解我们自己封装的router
前期准备工作:
framework compile 这个工程的目的是为了使用Abstractprocessor来处理注解,这个类的目的是专门处理注解的。
关键逻辑:使用javaPoet,javaPoet是用来生成java代码的一个java Library,生成的Java文件如下图三
图一:
图二:里面是扫描全部的router注解,分为三个模块的
图三:
1 初始化router ,设置哪些module都需要使用router
图四:
2 发起路由操作
图五:
此处的调用都是在IRouter接口里面能找到的,里面定义了路由支持哪些
router.build("param")的目的是为了把定义的pageridentity.xxxx设置到mRouterRequest的extra中,这么做的目的是为了后续根据key寻找map中的value,以便于在后续的图七中使用mRouterRequest.getExta,来拿到对应Key的value,
图六:
3 router.build(...).go(context)
go的逻辑:其中最重要的是getintent(context)的逻辑,
geIntent的逻辑
图七:
图八
补充:
我们自己封装的router支持数组类型的声明,支持多个值
http注解器
我们在Http请求的时候也使用了注解的原理,将对应的requestType和对应的Response放到map里面
https://juejin.im/post/584d4b5b0ce463005c5dc444这篇文章写的不错,关于javapoet中addStatement的用法