Gradle-动态移除清单文件中的权限
Gradle-动态移除清单文件中的权限
RT, 项目中有这样一个需求,需要将A项目中的界面添加到另一个项目B中,因为A项目中的界面需要用到某些权限,而B项目中也定义了这些权限,B项目中的权限受版本或其它关系,不能被A项目中的权限覆盖,所以希望在对A项目打aar包时,把aar包中的清单文件里的所有关于权限定义的部分删除掉,简单的说,就是这样:
这边想了不少办法,有一种做法是将权限声明成“tools:remove”
, 这是Google新支持的特性,但问题是如果将这些权限都声明成“tools:remove”
,那A项目就用不了这些权限了,所以想了想还是从Gradle入手,翻了不少资料,终于解决了这个需求,这里通过自定义Gradle插件的方式来解决这个问题,具体步骤如下:
-
在当前项目的根目录下新建一个模块,命名为
buildSrc
, 然后添加指定的文件:注意:这个module的名称必须为
buildSrc
.因为我们创建的这个module是AS专门用来写插件的,会自动参与编译.创建好之后删除Android那一堆东西,什么java代码,res,清单文件等.只剩下build.gradle
和.gitignore
把
build.gradle
文件内容改成:repositories { google() jcenter() } apply { plugin 'groovy' plugin 'java-gradle-plugin' } dependencies { implementation gradleApi() implementation localGroovy() implementation "commons-io:commons-io:2.6" }
-
在
main
文件夹下面创建文件夹groovy
, 然后使用Gradle sync一下.没啥问题的话,应该能编译过.然后在groovy
文件夹下面创建包名com.test.xxx
, 包名可以任意指定,然后创建一个空文件,名字叫ManifestFormatPlugin.groovy
package com.test.xxx import org.gradle.api.Plugin import org.gradle.api.Project class ManifestFormatPlugin implements Plugin<Project> { @Override void apply(Project project) { project.afterEvaluate { // 1. Find the specified task def processManifestTask = project.tasks.findByName("processReleaseManifest") if (processManifestTask != null) { // 2. Create a new Gradle task to remove permissions in the "AndroidManifest.xml" def parseDebugTask = project.tasks.create("RemovePermissionTask", RemovePermissionTask.class) // 3. Set to execute immediately after the specified task processManifestTask.finalizedBy(parseDebugTask) } else { println("can not found specified task [processReleaseManifest]") } } } }
这里声明了一个插件,名字叫做:
ManifestFormatPlugin
, 它会在Gradle构建processReleaseManifest
这个任务之后,自动执行我们新定义的Task:RemovePermissionTask
,RemovePermissionTask
这个文件的内容如下:package com.test.xxx import groovy.xml.XmlSlurper import groovy.xml.slurpersupport.NodeChild; import org.gradle.api.DefaultTask; import org.gradle.api.tasks.TaskAction; class RemovePermissionTask extends DefaultTask { @TaskAction void doAction() { // 1. Find the merged manifest file def file = new File(project.buildDir, "/intermediates/merged_manifest/release/AndroidManifest.xml") if (!file.exists()) { println("can not found merged manifest file") return } // 2. Get the content of the manifest file def manifestContent = file.getText() println("prepare to remove all permissions in the merged Manifest...") removePermission(file, manifestContent) } /** * Remove all permissions defined in the manifest file * @param file The "AndroidManifest.xml" file * @param manifestContent Content of the "AndroidManifest.xml" */ static void removePermission(File file, String manifestContent) { def manifestXML = new XmlSlurper(false, false).parseText(manifestContent) manifestXML.'*'.each { node -> if (node.name() == "uses-permission") { node.replaceNode {} } } def serializeContent = groovy.xml.XmlUtil.serialize(manifestXML) file.write(serializeContent) // // use XMLParser to parse the manifest file // def manifestXML = new XmlParser().parseText(manifestContent) // manifestXML.'**'.each { node -> // if (node.name() == "uses-permission") { // node.replaceNode {} // } // } // // new XmlNodePrinter().print(manifestXML) } }
-
然后在你最终想要打aar包的模块上应用该插件,比如我想把项目的
app
模块打成一个aar包,那就在app
模块的build.gradle
上方加入下列语句:import com.test.xxx.ManifestFormatPlugin apply plugin: ManifestFormatPlugin
比如我的加完之后是这个样子:
-
对所在的模块进行aar打包,查看输出结果:
可以看到清单文件中关于 权限声明的部分已经被顺利删除掉了。
参考链接
- Gradle系列(四) Gradle插件
- Gradle 插件练习-动态移除权限
- Android Gradle 插件开发入门指南
- StackOverFlow: How to dynamically edit Android Manifest ...
- Groovy: Get XML Tag first level
- 简书:1.5_任务依赖关系和排序
- 删除第三方AAR多请求的权限
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2019-11-01 Socket: Java Socket 几个重要的TCP/IP选项解析(转)
2016-11-01 Source Insight 基本使用(1)-使用Source Insight查看Android Framework 源码