利用编译时注解来解决android权限请求问题
这几天在开大神写的Dagger2 和 butterknife 这俩货同时用到了java中的一个特性就是编译时注解。注解在项目中是经常在使用的,比如标志是继承方法的 @Override。这些注解只有在我们写代码的时候才会发挥作用并不会。
其实注释一共有3种,代码时,编译时,运行时。字面意思就是它的运行的范围。很多开源项目通过一局注释就能完成很多工做多是利用了编译时,和运行时这两种注释。其中运行时注解一般时通过在main方法种拿到注释的类再通过反射来进行一些特别的操作。一说到反射这个词我其实是很敏感的,反射的效率真的不是很高,所以能不用就不用,这也是上面提到的两个大神级项目不用运行时注解而是用编译时注解的原因。
如何只是通过一个简单的注解就实现后面各种复杂的逻辑呢?这里就用到java自身的机制了,每次我们打包生成apk就是需要把java变成通用的语言让android的虚拟机进行识别,这个时候时会对java中所有的注释进行检测的这个检测的过程需要我们继承AbstractProcessor类去实现。
当然还要有注释的定义了注释为我们提供了4个基本的注解来修饰我们的自定义注解分别是:
- @Target 用来说明对象的范围,这个能标记你自定义的注解修饰的内容的类型
- @retention 标记它是怎样的注解类型编译时是 Class
- @Documented javadoc 标识的注解
- @Inherited.阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
首先新建一个项目要对它进行如下的构造
我在项目里建立了一个java的library(一定是java的呀!android的library是没有AbstractProcessor)和一个android的library(这个里面主要是对一些android方面的逻辑进行处理的位置)
在java library中建立一个注解类
~java
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface PAccept {
String value();
}
~
这个用来标志请求权限成功的回掉函数
再建立一个注解类
~java
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface PReject {
String value();
}
~
这个来标记失败的回调函数
然后写建立一个MyProcessor的类继承AbstractProcessor并且要建立如下的代码
这些代码是保证再编译阶段会运行我们自己写的AbstractProcessor。
下面是来让我们看看我们的MyProcessor里做了写什么吧
~~~java
@SupportedAnnotationTypes({“com.example.PAccept”,”com.example.PReject”})
public class MyProcessor extends AbstractProcessor {
public static final String SUFFIX = “$$PermissionAdapter”;
private Map<String,AdapterClass> mMaps = new HashMap<>();
private Elements elementUtils;
private Filer filer;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
elementUtils = processingEnv.getElementUtils();
filer = processingEnv.getFiler();
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public boolean process(Set<? extends TypeElement> annotatio