【问题标题】:Get Android application package name during annotation processing注解处理时获取Android应用包名
【发布时间】:2016-06-24 03:18:46
【问题描述】:

我正在开发一个库,该库在编译时(点击构建时)基于带注释的类和字段生成类文件。到目前为止一切都很好(可以生成类)。但是,我在启动应用程序时如何找到这样一个生成的类有一个问题(该类需要在ApplicationonCreate 方法中访问)。

代码如下所示:

- Application class of an Android app -
@Override
public void onCreate() {
    super.onCreate();
    MyLib.setup(this);
}

MyLib 类中,需要执行以下操作:

public void setup(Application app) {
    String className = String.format("%s.%s", "packageName", "generatedClassName");
    Class<?> myGeneratedClass = Class.forName(className);
    ...
}

问题是我不知道如何找到类而不知道它的包名,也不知道如何找到它的包名。

我可以想到一种方法来做到这一点,将包名称传递到 @MyAnnotation("package_name") 之类的注释中,以便在编译时生成类并在运行时获取该类时使用它。

但是我只是想知道是否还有其他更清洁的方法可以实现这一目标。有没有办法: 1.注解处理时获取Application包名 2.在运行时寻找一个类而不知道它的包(只知道Application包)。我确实在MyLib.setup() 中尝试了Package.getPackages()。但是这会返回一个空数组。

【问题讨论】:

    标签: java android annotation-processing


    【解决方案1】:

    这是一个经过充分研究的问题。最简单的方法是让您的用户注释应用程序包(是的,annotating a package is possible)或通过 javac parameter 传递应用程序包的名称(android-apt 和新版本的 Android Gradle 插件对这些具有原生支持)。这很便宜,可以让您快速上手。

    启发式地获取包名是可能的,AndroidAnnotations 有一大段代码(更准确地说,是finding AndroidManifest.xmllocating R.java),它们都可以给出应用程序包。请注意,这些方法并不漂亮。请注意,AndroidAnnotations 具有插件系统,因此您可以通过编写插件并声明对其主处理器的依赖关系来访问该功能,而无需重新执行它们的工作。

    最后,您可以编写自己的 Gradle 插件并直接访问此类信息。

    【讨论】:

    • 非常感谢您的回答。信息量很大。我很高兴发现 AndroidAnnotations 有这些方法。我发现插件选项非常有趣。您能否提供更多有关它的信息?谢谢
    【解决方案2】:

    覆盖应用程序类

    private static Context sContext;
    
        @Override
           protected void attachBaseContext(Context base) {
           super.attachBaseContext(base);
           sContext = base;
        }
    
        public static Context getAppContext() {
            return sContext;
        }
    

    获取包名

    YourApplication.getAppContext().getPackageName();
    

    编辑: 获取从AbstractProcessor 扩展的类中带注释元素的包名 你可以用这个

    final String originalPackageName = element.getEnclosingElement().toString(); 
    

    其中元素是 TypeElement instance

    【讨论】:

    • 我知道该怎么做,但正如我在问题中提到的,我需要在编译时获取包名,这意味着它必须以某种方式从注释处理器(即在public boolean process(Set&lt;? extends TypeElement&gt; annotations, RoundEnvironment roundEnv) 函数。但是谢谢
    • 已添加。希望对你有帮助
    • 是的,如果我注释Application类并使用它来获取包,这可以实现。在我的例子中,我为另一个类使用了注释,我不愿意为 Application 类添加另一个注释,只是为了在编译时获取它的包 - 因为这需要用户需要执行一个额外的步骤才能使用我的库写作。我不确定如果不做你提到的和我在问题中提到的,是否可以做到这一点。但是在我决定采取这两个选项之前,我仍然想寻找另一个解决方案。
    • 也许你可以做一些像android注释那样的事情。在与更改名称的原始类相同的包中生成新类?
    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多