我目前正在努力创建一个自定义注释,它与@TargetApi()
完成相同的工作但是我的口味。
在我的情况下,我需要使用某种方法(在一个名为Navigator
的类中)将我的应用程序重定向到另一个屏幕,但我只在其中一种风格中创建了这个屏幕。因此,当我切换到另一个Build Variant时,我的Android Studio会显示错误:Unresolved reference
,正如所料。
我有3种口味:device1
,device2
和device3
。另外device1
有这个独特的屏幕(称为UniqueActivity
),并且所有风格都可以访问Navigator
类。
我看到这样的用例:
@TargetFlavor(currentFlavor = BuildConfig.FLAVOR, targetFlavor = "device1")
因此,当选定的flavor(通过Build Variant)与目标flavor不对应时,我想到了预处理器注释以忽略方法。我跟着this article。
这就是我所取得的成就:
TargetFlavor注释:
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface TargetFlavor {
String currentFlavor();
String targetFlavor();
}
TargetFlavorProcessor:
public class TargetFlavorProcessor extends AbstractProcessor {
private Filer filer;
private Messager messager;
private Elements elements;
private Map<String, Boolean> methodWithFlavor;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
filer = processingEnv.getFiler();
messager = processingEnv.getMessager();
elements = processingEnv.getElementUtils();
methodWithFlavor = new HashMap<>();
}
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
for (Element element : roundEnvironment.getElementsAnnotatedWith(TargetFlavor.class)) {
if (element.getKind() != ElementKind.METHOD) {
messager.printMessage(Diagnostic.Kind.ERROR, "Must be applied on methods");
return true;
}
TypeElement typeElement = (TypeElement) element;
TargetFlavor annotation = element.getAnnotation(TargetFlavor.class);
methodWithFlavor.put(
typeElement.getSimpleName().toString(),
annotation.targetFlavor().equals(annotation.currentFlavor()));
}
for (Map.Entry<String, Boolean> methods : methodWithFlavor.entrySet()) {
if (!methods.getValue()) {
// Here, I want the compiler to ignore method which not correspond
}
}
return true;
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return Collections.singleton(TargetFlavor.class.getCanonicalName());
}
@Override
public SourceVersion getSupportedSourceVersion() {return SourceVersion.latest();}
}
但是当我想强制我的编译器忽略@TargetFlavor()
选择的某些方法时,我就陷入困境。
有更好的方法可以做到这一点,还是我正确地做到了这一点?