android 动态切换aar_Android应用开发之动态更改AndroidManifest.xml中节点属性操作教程...

本文介绍了在Android开发中,如何通过Gradle和Groovy动态更改AndroidManifest.xml的节点属性,特别是在需要动态切换aar包或处理多进程需求时,提供了一种解决方案,避免手动修改和占位符替换的不便。示例代码展示了如何在打包时动态添加或替换activity、service的android:process属性。
摘要由CSDN通过智能技术生成

本文将带你了解Android应用开发之动态更改AndroidManifest.xml中节点属性操作教程,希望本文对大家学Android有所帮助。

在Android使用Gradle进行编译打包时,有时候需要动态更改AndroidManifest.xml中application、activity等节点属性,大多数情况下一般通过占位符替换即可完成相应的功能,但存在一些比较复杂的情况,如果还是采用占位符替换,显得就不再方便或者不能达到所想要的目的。下面我将介绍另一种通过Groovy动态更改AndroidManifest.xml节点属性的方法。

先说一下我遇到的问题,我的问题是我想打两种不同的aar包,给不同应用使用,其中一个需要包用来跨进程使用,因此需要给AndroidManifest中的一些activity、service等增加android:process属性,正常情况下肯定不能打包的时候手动修改增加改属性,所以希望通过控制开关或者属性来动态控制打包结果。这里如果使用占位符的方式来做,就需要在所有需要多进程的activity或者service等中都需要添加android:process属性,这不方便阅读和后续版本开发,因为如果这样去做,开发的时候都需要注意添加这个属性,觉得很不方便,类似这样的需求还有例如替换theme等等。面对这样的需求如果能够在打包编译的时候动态替换那就即可以完成需求又能解决后续开发存在的问题。

通过参考网上的一些资料和gradle编译过程,了解到在打包生成变体时会在processManifest时生成一个缓存AndroidManifest.xml文件,然后打包时使用的manifest文件就是该文件,因此在该task执行完成之后通过解析改XML文件,然后动态添加和替换属性即可。代码如下:

?12345678910111213141516171819202122232425262728293031android.getLibraryVariants().all   { variant ->    variant.outputs.each()   {        //single_process   用于控制独立进程开关        it.processManifest.doLast   { task   ->            if(project.hasProperty("single_process")   &&   project.property("single_process").equals("2")){                //受gradle版本影响,AndroidManifest.xml文件位置有所不同                def   manifestFile = new File("${buildDir}/intermediates/bundles/${it.dirName}/AndroidManifest.xml")                if(!manifestFile.exists()){                    def   dir=''                    it.baseName.split('-').each   {                        dir=dir+it+'/'                    }                    manifestFile=new   File("${buildDir}/intermediates/manifests/full/${dir}AndroidManifest.xml")                }                def   XmlParser = new   XmlParser()                def   manifest =   XmlParser.parse(manifestFile)                def   processTag =   "android:process"                def   android = new Namespace('http://schemas.android.com/apk/res/android',   'android')                def   nodes=manifest.application[0].'*'.findAll{                    (it.name()=='activity'||it.name()=='service')&&it.attribute(android.process)==null   //选择要修改的节点                }                nodes.each{                    it.attributes().put(processTag,":wallet_sdk")                }                PrintWriter   pw = new   PrintWriter(manifestFile)                pw.write(groovy.xml.XmlUtil.serialize(manifest))                pw.close()            }        }    }}

值得注意的是,受gradle版本问题,所以打aar包时manifest的文件位置存在不一致,我曾测试使用3.1.2的代码放到2.2中发现找不到manifest文件,同时it.dirName属性(product   flavor输出目录)也在3.1.2中获取为空值。如果是想对打包APK时进行替换,AndroidManifest.xml都能在intermediates/manifests/full目录下找到,需要修改的是因plugin不同对应的variant不一样,将getLibraryVariants()替换成applicationVariants,如下:

?1234567android.applicationVariants.all { variant   -> variant.outputs.each() {  it.processManifest.doLast {   task ->//manifest操作  } }}

关于Groovy对XML更多的操作,可查看相关文档。

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值