一、Runtime
在运行时(Runtime)通过反射机制运行处理的注解
/**
* PageName注解
*
* @author 胡永城
* @date 2018/1/23
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PageName {
String value();
}
@Test
public void test_class() throws Exception {
Class clazz = Class.forName("com.hualala.supplychain.mendianbao.app.bill.BillActivity");
Annotation anno = clazz.getAnnotation(PageName.class);
if (anno != null && anno instanceof PageName) {
System.out.println(((PageName) anno).value());
} else {
System.out.println("没有获取到注解");
}
}
二、Compile time
编译时(Compile time)处理注解
2.1 Annotation Processor
用来在编译时扫描和处理注解(Annotation)
- 2.1.1 annotationProcessor
annotationProcessor是Google提供的插件,协助Android Studio 处理annotation processors,允许配置只在编译时作为注解处理器的依赖,而不添加到最后的APK或library中 - 2.1.2 android-apt
android-apt是由一位开发者自己开发的apt框架,随着Android Gradle 插件 2.2 版本的发布,Android Gradle 插件提供了名为 annotationProcessor 的功能来完全代替 android-apt
2.2 com.google.auto.service:auto-service:1.0-rc2
google 公司出品,用于自动为 JAVA Processor 生成 META-INF 信息 ,注册你自定义的注解器
2.3 com.squareup:javapoet:1.9.0
squre 公司出品,用于用于生成.java源文件的Java API
三、使用
3.1 定义注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.CLASS)
public @interface ActionAnnotation {
String filter();
String name();
String right();
String categoryName();
int resIcon();
int standardIcon();
int sceneIcon();
boolean isScm();
boolean isOnly();
boolean isDistributionAction();
boolean isThirdShopAction();
boolean isShowScene();
boolean isShowStandard();
}
3.2 使用注解
@ActionAnnotation(
filter = "purchase",
name = "订货",
right = "mendianbao.mendianbaodinghuodan.add",
categoryName = STOCK_MANAGEMENT,
resIcon = R.drawable.ic_action_dinghuo,
sceneIcon = R.drawable.baohuo,
isShowScene = true,
standardIcon = R.drawable.standard_baohuo,
isShowStandard = true,
isScm = true,
isOnly = false,
isDistributionAction = false,
isThirdShopAction = true)
private String purchase;
3.3 获取注解并生成Java文件
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
if (!mIsFirst) {
return true;
}
List<Action> list = new ArrayList<>();
for (Element element : roundEnvironment.getElementsAnnotatedWith(ActionAnnotation.class)) {
if (element.getKind() == ElementKind.FIELD) {
ActionAnnotation actionAnnotation = element.getAnnotation(ActionAnnotation.class);
Action action = new Action();
action.setFilter(actionAnnotation.filter());
action.setName(actionAnnotation.name());
action.setRight(actionAnnotation.right());
action.setCategoryName(actionAnnotation.categoryName());
action.setResIcon(actionAnnotation.resIcon());
action.setSceneIcon(actionAnnotation.sceneIcon());
action.setShowScene(actionAnnotation.isShowScene());
action.setStandardIcon(actionAnnotation.standardIcon());
action.setShowStandard(actionAnnotation.isShowStandard());
action.setScm(actionAnnotation.isScm());
action.setOnly(actionAnnotation.isOnly());
action.setDistributionAction(actionAnnotation.isDistributionAction());
action.setThirdShopAction(actionAnnotation.isThirdShopAction());
list.add(action);
}
}
//sceneIcon
FieldSpec actionScene = FieldSpec.builder(ParameterizedTypeName.get(Map.class, String.class, Integer.class), "ACTION_ICON")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.initializer("new $T()", HashMap.class)
.build();
CodeBlock.Builder codeBlockScene = CodeBlock.builder();
//循环添加
for (Action action : list) {
if (action.isShowScene()) {
codeBlockScene.addStatement("ACTION_ICON.put($S, $L)", action.getFilter(), action.getSceneIcon());
}
}
TypeSpec finderClass = TypeSpec.classBuilder("IconHelper")
.addModifiers(Modifier.PUBLIC)
.addJavadoc("Automatically generated file. DO NOT MODIFY")
.addField(actionScene)
.addStaticBlock(codeBlockScene.build())
.build();
JavaFile javaFile = JavaFile.builder("com.hualala.mendianbao.injecter", finderClass)
.build();
try {
javaFile.writeTo(mFiler);
mIsFirst = false;
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
网友评论