gradle(4.1.0以上和4.0以下) 对AndroidManifest.xml文件增删改查

前言

现项目有一个需求,不同的渠道打包,需要对AndroidManifest.xml进行增删修改,简单的修改可以通过productFlavors占位符替换即可完成相应的功能,但是有时候我们想要进行增加或者删除呢,比如需要删除一个结点(四大组件)怎么办?或者想要动态增加一个结点怎么办呢?大家首先想到的是通过gradle编译打包的时候进行修改,但是gradle版本的不同,对向下兼容又做的不好,就需要我们对各个版本进行去适配,因为现在用的最多的是4.0以上或者3.5的版本,我就拿这两个版本做例子:

gradle3.5动态修改Manifest文件

网上也有很多种不同的实现,我这里只讲解我自己在项目上用的一种,实际上gradle就是一种工具,只要能实现我们的需求就行。


android {
android.applicationVariants.all { variant ->
  variant.outputs.all { output ->
  output.processResources.doFirst { pm ->
 String manifestPath = output.processResources.manifestFile
 String manifestContent = file(manifestPath).getText()
def android = new Namespace("http://schemas.android.com/apk/res/android", "android")
def xml = new XmlParser().parseText(manifestContent)
  xml.application[0].appendNode("meta-data", ['android:name': 'channel', 'android:value': 'test'])
 xml.application[0].appendNode("provider", ['android:name'       : 'com.test.provider',
                                                           'android:authorities': 'com.test.provider',
                                                           'android:enabled'    : 'true',
                                                           'android:exported'   : 'true'])
 xml.application[0].'*'.removeAll {
                            (it.attributes()[android.name] == 'com.test.provider')
                        }
  def nodes=xml.application[0].'*'.findAll{
                           (it.name()=='provider' && provider.attributes()[android.name] == 'com.test.provider')       }
 nodes.each { provider->
                       println 'provider attributes ' + provider.attributes()
                        println 'provider name ' + provider.attributes()[android.name]
                     }

def serialize = groovy.xml.XmlUtil.serialize(xml)
                file(manifestPath).write(serialize)
}
}
}
}

以上就是对AndroidManifest的增删改查,另外教大家一个可以查看gradle源码的小技巧,在我们项目module(通常对应的是app)中的build.gradle里面增加:

android {
dependencies{
 implementation "com.android.tools.build:gradle:3.5.2"
}
android.applicationVariants.all { variant ->
        variant.outputs.all { output ->
}
}
}

这样就可以看到里面的源码了,找到BaseVariantOutput类,里面有:

 /**
     * Returns the Android Resources processing task.
     *
     * @deprecated Use {@link #getProcessResourcesProvider()}
     */
    @NonNull
    @Deprecated
    ProcessAndroidResources getProcessResources();

    /**
     * Returns the {@link TaskProvider} for the Android Resources processing task.
     *
     * <p>Prefer this to {@link #getProcessResources()} as it triggers eager configuration of the
     * task.
     */
    @NonNull
    TaskProvider<ProcessAndroidResources> getProcessResourcesProvider();

    /**
     * Returns the manifest merging task.
     *
     * @deprecated Use {@link #getProcessManifestProvider()}
     */
    @NonNull
    @Deprecated
    ManifestProcessorTask getProcessManifest();

    /**
     * Returns the {@link TaskProvider} for the manifest merging task
     *
     * <p>Prefer this to {@link #getProcessManifest()} as it triggers eager configuration of the
     * task.
     */
    @NonNull
    TaskProvider<ManifestProcessorTask> getProcessManifestProvider();

发现咱们刚才用的getProcessResources过时了,但是在3.5还是能使用的,最终改变的Manifest文件会放到
app/build/intermediates/merged_manifests里面,getProcessResourcesProvider的使用跟getProcessResources差不多

 output.processResourcesProvider.get().doFirst {
...
}

用getProcessManifest和getProcessManifestProvider也能实现上面的功能的,我在这里就不一一列出来了,大家可以进去看看ManifestProcessorTask这个类里面的函数:

 /** The processed Manifests files folder. */
    @NonNull
    @OutputDirectory
    public DirectoryProperty getManifestOutputDirectory() {
        return manifestOutputDirectory;
    }
 /**
     * The bundle manifest which is consumed by the bundletool (as opposed to the one packaged with
     * the apk when built directly).
     */
    @OutputDirectory
    @Optional
    public File getBundleManifestOutputDirectory() {
        return bundleManifestOutputDirectory;
    }

上面这两个函数应该都可以获取manifest的路径,这两个函数的区别我没有仔细研究,有兴趣的可以去查看一下

由于项目工程升级到4.1.2了,发现上面的函数都行不通了,修改的文件通过app/build/intermediates/merged_manifests路径也能看到,但是就是不打包到APK里面,让我很苦恼,最后发现gradle4.0升级后,改变路径了,所生成的manifest文件放到了app/build/intermediates/merged_manifest里面(真坑人,让我找了好长时间),而且之前使用的getProcessResources也不行了,下面是4.0以上的写法

gradle4.1.2(这是我项目的版本)动态修改Manifest文件

 android.applicationVariants.all { variant ->
variant.outputs.all { output ->
output.processManifestProvider.get().doFirst { 
                def manifestPath = new File("${buildDir}/intermediates/merged_manifest/${variant.name}/out/AndroidManifest.xml")
 String manifestContent = file(manifestPath).getText()
下面的就和上面的一样了
}
}
}

我使用processResources就不行,必须使用processManifestProvider函数,而且4.0以上的ManifestProcessorTask类里面的内容也变了,没有获取路径的函数了,我只能手写路径。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358

推荐阅读更多精彩内容