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

时间:2018-02-23 15:52:59

标签: java android gradle annotations kotlin

我目前正在努力创建一个自定义注释,它与@TargetApi()完成相同的工作但是我的口味。

案例

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

我有3种口味:device1device2device3。另外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()选择的某些方法时,我就陷入困境。

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

0 个答案:

没有答案