manifest


manifest

文章插图
作者:刘天宇(谦风)
前言工程腐化是app迭代过程中,一个非常棘手的问题,涉及到广泛而细碎的具体细节,对研发效能&体验、工程&产物质量、稳定性、包大小、性能,都有相对“隐蔽”而间接的影响 。一般不会造成不可承受的障碍,却时常蹦出来导致“阵痛”,有点像蛀牙或智齿,到了一定程度不拔不行,但不同的是,工程的腐化很难通过一次性“拔除”来根治,任何一次“拔除”之后,需要有效的可持续治理方案,形成常态化的防腐体系 。
工程腐化拆解来看,是组成app的代码工程中,工程结构本身,以及各类“元素”(manifest、代码、资源、so、配置)的腐化 。优酷架构团队近年来,持续在进行思考、实践与治理,并沉淀了一些技术、工具、方案 。现逐一分类汇总,辅以相关领域知识讲解,整理成为《向工程腐化开炮》系列技术文章,分享给大家 。希望更多同学,一起加入到与工程腐化的这场持久战中 。
系列文章第一篇《向工程腐化开炮 | proguard治理》 。本文为系列文章第二篇,将聚焦于manifest这一细分领域 。对工程腐化,直接开炮!
背景manifest是指apk中AndroidManifest.xml文件,作为apk整体信息清单,包含很多重要信息,对app构建期处理、运行时行为、应用商店过滤等,均有至关重要影响 。
manifest

文章插图
清单内容&影响
当AndroidManifest.xml文件中内容,发生非预期改变时,会带来意想不到的后果 。例如:minSdkVersion变小,上线后低版本os用户升级到最新apk,导致严重的使用体验问题;targetSdkVersion升高,os对app运行时的特定处理发生变化,未适配代码crash/功能异常;新权限被引入,隐私协议未声明,被监管机构发现 。上述这些问题,都只是清单文件中一个“微小”的配置值变化引发,清单的腐化导致这类非预期变化,发生的可能性越来越高 。manifest治理正是围绕AndroidManifest.xml的内容整理与防控,逐步展开的 。
基础知识本章先简要介绍一些基础知识,方便大家对manifest有一个“框架性”的清晰认知 。首先,看一下AndroidManifest.xml文件的生成(合并)过程 。
1.1 合并流程
app工程、aar类型的subproject工程、外部依赖的aar模块,均包含AndroidManifest.xml文件 。在apk构建过程中,这些AndroidManifest.xml文件经过合并后(+一些额外处理),生成唯一的AndroidManifest.xml文件,经过编译后最终放置到apk根目录 。
合并是从低优先级,逐步向高优先级进行 。横向是不同来源的优先级;模块间优先级从高到低,为在app工程中的声明顺序;build variant、build type、product flavor之间的优先级逐渐降低;product flavor如果包含多个dimension,优先级从高到低为flavorDimensions中指定的顺序 。
manifest

文章插图
AndroidManifest.xml优先级&合并顺序
【manifest】在合并过程中,相同xml元素(一般是android:name属性值,或者元素标签)属性会有合并冲突情况,基本原则是:高优先级和低优先级属性值,如果都存在且不一致,则视为冲突 。由于清单文件中元素/属性的多样性,实际规则要复杂很多,具体可以参考google官方文档 。合并冲突的解决,除了修改对应AndroidManifest.xml文件之外,还可以通过在app工程AndroidManifest.xml中,增加“合并规则标记”实现 。此外,即使未发生冲突,当需要控制清单内容时,也可以通过同样方式实现,接下来对此进行介绍 。
1.2 合并控制
前文提到的“合并规则标记”,通过对xml节点和属性这两个不同颗粒度,指定合并规则,来实现合并结果控制 。首先,需要在manifest根节点,增加tools命名空间:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.myapplication"xmlns:tools="http://schemas.android.com/tools">然后,根据具体情况,在节点中添加对应tools:属性 。
manifest

文章插图
合并规则标记说明
合并控制的具体规则,请参考官方文档,在此不详述 。
1.3 manifest占位符
除了上述合并控制,还可以通过manifest占位符,控制清单中节点的属性值 。
# build.gradle文件中定义变量和值android {defaultConfig {manifestPlaceholders = [customKey:"customValue", ...]}...}# AndroidManifest.xml文件中使用占位符<intent-filter ... ><data android:scheme="https" android:host="${customKey}" ... />...</intent-filter><meta-data android:name="sampleMeta" android:value=https://www.doubo5.com/"${customKey}"/>

秒懂生活扩展阅读