Android - 自定义注释TargetFlavor,如TargetApi,但味道

MrL*_*ond 8 java android annotations gradle kotlin

我目前正在创建一个自定义注释,它可以完成@TargetApi()与我的风格相同的工作.

案子

在我的情况下,我需要使用某种方法(在一个被调用的类中Navigator)将我的应用程序重定向到另一个屏幕,但我只在其中一种风格中创建了这个屏幕.因此,当我切换到另一个Build Variant时,我的Android Studio会显示错误:Unresolved reference正如预期的那样.

我有3种口味:device1,device2device3.还有device1这个独特的屏幕(称为UniqueActivity),所有口味都可以访问Navigator课程.

我看到这样的用例:

@TargetFlavor(currentFlavor = BuildConfig.FLAVOR, targetFlavor = "device1")
Run Code Online (Sandbox Code Playgroud)

(近乎完美)的解决方案

所以我想到预处理器注释忽略方法时所选的味道(通过Build Variant)与目标味道不对应.我跟着这篇文章.

这就是我取得的成就:

TargetFlavor注释:

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface TargetFlavor {
    String currentFlavor();
    String targetFlavor();
}
Run Code Online (Sandbox Code Playgroud)

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();}

}
Run Code Online (Sandbox Code Playgroud)

但是当我想强制我的编译器忽略选择的某些方法时,我就陷入了困境@TargetFlavor().

有没有更好的方法来做到这一点,还是我正确地做到了这一点?