使用注释传递值时获取Android R类?

时间:2017-04-18 16:01:56

标签: java android resources annotation-processing

我有这个注释BindPrefRes.class

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface BindPrefRes {
    @StringRes int value();
}

现在,当我在任何这样的Android项目中使用该注释时:

@BindPrefRes(R.string.app_name) String appName;

我试图通过javax.annotation.processing.AbstractProcessor

获取价值
int value = element.getAnnotation(BindPrefRes.class).value()

我得到了实际的int(2131230753),我理解这是预期的行为。但是,如何将此int解析回字段(R.string.app_name),或者至少解析该字段的字符串表示形式("R.string.app_name")?

source code is on GitHub,如果我不清楚的话。

1 个答案:

答案 0 :(得分:0)

简短回答:您应该尽可能避免这样做,因为可能根本无法获得所需的信息。例如,如果Gradle(或其他构建系统)开始使用注释处理器开始支持增量构建,那么在处理器运行时,R类可能不会出现在编译路径中。

答案很长:有两种方法:

  1. 扫描R
  2. 的源代码
  3. 遍历找到的R类中的每个字段,并将所有常量添加到Map
  4. 将从注释中收到的值与来自Map的常量相关联
  5. One implementation这种方法(由于某种原因依赖于非公开的Javac内部)可以在ButterKnife来源中找到)。

    Another one由Android Annotations项目维护(您可以通过将处理器作为Android Annotations处理器的插件来复制或直接访问它)。

    也丑陋

    使用Oracle专有的半稳定树API直接内省@BindPrefRes(R.string.app_name)的源代码。我建议尽可能采用这种方式,因为它的副作用较少。

    Obtain a TreePath注释值,将其强制转换为ExpressionTree并手动解析内容。