您可以 read/amend/replace AndroidManifest.xml 文件使用自定义注释处理器吗
Can you read/amend/replace AndroidManifest.xml file with a Custom Annotation Processor
我正在调查 Android 应用程序的自定义注释处理器。
我有一个用例,我希望能够使用注释处理器来 read/amend AndroidManifest.xml
并为其中提到的所有活动添加以下意图部分?
<intent-filter>
<action android:name="com.my.package.name.my_activity.open"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
这可能吗?
这是一个非常有趣的问题,但我认为您无法使用注释处理器完成这样的任务,因为它们在 Kotlin/Java 代码生成级别工作。
如何注释 XML @Something
并使其仍然有效 XML?
看看这个:
KoltinConf18 - Annotation processing in Kotlin
Zack 在 7:18 中检查了 Java 中的注释处理,它基本上说:
- 编译时发生
- 并且您不能修改代码,只能生成更多
因此,通过使用准系统注释处理,您无法真正修改已经存在的 AndroidManifest.xml
。
另一种方法是编写一个 Gradle 插件来生成 XML 的那些位并将其与项目中已经存在的当前 XML 文件合并。
我脑海中的想法可能是:
- 创建注释并标记要引入该段代码的所有活动
- 在插件方面;当您正在编写 Gradle 任务时;您可以使用反射并找出哪些 classes 由此类扩展注释。 或者让程序员将这些活动放在源文件夹内的特定目录中,这样会更容易
- 有了完全限定的 class 名称,您可以查看
AndroidManifest.xml
中的 <activity>
节点,过滤掉与 class 不匹配的名称带注释的 class 姓名列表
- 用您要注入的代码修改这些节点。
要开始编写 Gradle 插件,请查看 here
一个简单的入门示例可以是:
步骤 1
如果插件太麻烦,您可以创建一个单独的模块来编写您的插件,但对于这个简单的示例,我决定将其直接放在 build.gradle.kts
中。它不需要是 kotlin Gradle 文件,但我对 Kotlin 比 Groovy 更精通:)
如您所见,我在项目的根目录中创建了一个文本 testFile.txt
。
在代码中,我只是导航到它并阅读它;打印它的内容然后修改它。
您可以用 AndroidManifes.xml
做同样的事情。然后,您需要递归地遍历 srcDir
中的源文件,查找所有由您的特殊注释注释的活动,并将所有完全限定的 class 名称存储在 List<String>
中。然后在 AndroidManifest
中进行必要的替换
请注意,使用此基本配置,Gradle 任务会出现在 others
类别内的 Gradle 选项卡中,更改它会稍微超出注释处理的范围.
第 2 步,利润
有效,如您所见,文件已更新,并且 println 语句显示文件在修改之前的先前内容
您可以有一个模板 AndroidManifest_template.xml,然后使用 gradle 任务遍历 AndroidManifest_template.xml 并生成将用于构建应用程序的真实 AndroidManifest.xml。
换句话说,AndroidManest.xml 将是构建的一个临时部分,您可以使用任何 XML 预处理器来获取模板并将其转换为真实文件。
如果您想根据应用的风格有条件地添加这些意图,您可以使用 gradle 风格和清单合并来实现这一点 - 在 https://developer.android.com/studio/build/build-variants[=12 阅读更多关于风格的信息=]
使用gradle修改manifest
的例子也可以参考下面的问题
我正在调查 Android 应用程序的自定义注释处理器。
我有一个用例,我希望能够使用注释处理器来 read/amend AndroidManifest.xml
并为其中提到的所有活动添加以下意图部分?
<intent-filter>
<action android:name="com.my.package.name.my_activity.open"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
这可能吗?
这是一个非常有趣的问题,但我认为您无法使用注释处理器完成这样的任务,因为它们在 Kotlin/Java 代码生成级别工作。
如何注释 XML @Something
并使其仍然有效 XML?
看看这个:
KoltinConf18 - Annotation processing in Kotlin
Zack 在 7:18 中检查了 Java 中的注释处理,它基本上说:
- 编译时发生
- 并且您不能修改代码,只能生成更多
因此,通过使用准系统注释处理,您无法真正修改已经存在的 AndroidManifest.xml
。
另一种方法是编写一个 Gradle 插件来生成 XML 的那些位并将其与项目中已经存在的当前 XML 文件合并。
我脑海中的想法可能是:
- 创建注释并标记要引入该段代码的所有活动
- 在插件方面;当您正在编写 Gradle 任务时;您可以使用反射并找出哪些 classes 由此类扩展注释。 或者让程序员将这些活动放在源文件夹内的特定目录中,这样会更容易
- 有了完全限定的 class 名称,您可以查看
AndroidManifest.xml
中的<activity>
节点,过滤掉与 class 不匹配的名称带注释的 class 姓名列表 - 用您要注入的代码修改这些节点。
要开始编写 Gradle 插件,请查看 here
一个简单的入门示例可以是:
步骤 1
如果插件太麻烦,您可以创建一个单独的模块来编写您的插件,但对于这个简单的示例,我决定将其直接放在 build.gradle.kts
中。它不需要是 kotlin Gradle 文件,但我对 Kotlin 比 Groovy 更精通:)
如您所见,我在项目的根目录中创建了一个文本 testFile.txt
。
在代码中,我只是导航到它并阅读它;打印它的内容然后修改它。
您可以用 AndroidManifes.xml
做同样的事情。然后,您需要递归地遍历 srcDir
中的源文件,查找所有由您的特殊注释注释的活动,并将所有完全限定的 class 名称存储在 List<String>
中。然后在 AndroidManifest
请注意,使用此基本配置,Gradle 任务会出现在 others
类别内的 Gradle 选项卡中,更改它会稍微超出注释处理的范围.
第 2 步,利润
有效,如您所见,文件已更新,并且 println 语句显示文件在修改之前的先前内容
您可以有一个模板 AndroidManifest_template.xml,然后使用 gradle 任务遍历 AndroidManifest_template.xml 并生成将用于构建应用程序的真实 AndroidManifest.xml。
换句话说,AndroidManest.xml 将是构建的一个临时部分,您可以使用任何 XML 预处理器来获取模板并将其转换为真实文件。
如果您想根据应用的风格有条件地添加这些意图,您可以使用 gradle 风格和清单合并来实现这一点 - 在 https://developer.android.com/studio/build/build-variants[=12 阅读更多关于风格的信息=]
使用gradle修改manifest
的例子也可以参考下面的问题