• Android清单文件合并的那些事


    APK文件只能包含一个AndroidManifest.xml文件,但Android Studio项目可以包含多个文件(通过buildSrc、导入的库引入)。因此,在构建应用时,Gradle构建会将所有清单文件合并到一个封装的APK的清单文件中。

    清单文件合并优先级

    清单合并工具

    • 可以使用Merged Manifest视图预览合并清单的效果并找出冲突错误。

    可以互相合并的基本清单文件,合并优先级如下(优先级由高到低):

    1. 清单文件构建变体
      如果变体有多个源集,其清单优先级由高到低如下:
      a、构建变体清单文件(如 src/demoDebug)
      b、构建类型清单(如 src/debug/)
      c、产品定制清单(如 src/demo/)
      如果使用的是定制纬度,清单优先级与每个维度在 flavorDimensions属性中的列示顺序(优先级高到低)对应。
    2. 应用模块的主清单文件
    3. 所包括库中的清单文件:如果有多个库,清单优先级与依赖顺序(库出现在 Gradle dependencies 块中的顺序)匹配。

    重要说明:build.gradle文件中的构建配置将替换合并清单文件中的任何对应属性。如build.gradle文件中的minSdkVersion将替换清单元素中的匹配属性。

    合并冲突启发式算法

    合并工具行为:

    • 元素中的属性绝不合并,仅使用优先级最高的清单中的属性。
    • android:required属性、元素使用OR合并,因此如果出现冲突,系统将采用“true”并始终包括某个清单所需的功能或者库。
    • 元素始终使用优先级较高的清单中的值,但以下情况除外:
      • 如果低优先级清单的 minSdkVersion值较高,除非应用 overrideLibrary合并规则。(minSdkVersion使用较大值)
      • 如果低优先级清单的 targetSdkVersion值较低,合并工具将使用高优先级清单中的值,但也会添加任何必要的系统权限。(targetSdkVersion使用较大值)
    • 绝不会在清单之间匹配元素。每个元素都被视为唯一元素并添加到合并清单中。

    重点:清单合并不依赖默认属性值。因此,应该按照期望明确定义每个属性。(每个属性的默认值都会记录在Manifest reference:https://developer.android.com/guide/topics/manifest/manifest-intro)

    合并规则标记

    可以针对整个元素或者只对元素中的特定属性应用标记。
    所以标记都属于Android tools命名空间,因此必须现在元素中声明此命名空间:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.myapp"
        xmlns:tools="http://schemas.android.com/tools">
    

    节点标记:

    • tools:node="merge" ——默认行为,合并此标记中的所有属性以及所有嵌套元素。
    • tools:node="merge-only-attributes" ——仅合并此标记中的属性,不合并嵌套元素
    • tools:node="remove" ——从合并清单中删除此元素,可以删除低优先级清单的元素
    • tools:node="removeAll" ——会删除与此元素类型相匹配的所有元素(同一父元素内)
    • tools:node="replace" ——完全替换低优先级元素
    • tools:node="strict" ——标记元素在低优先级清单中的配置与高优先级清单不完全匹配,会触发构建失败。(默认行为会向合并清单添加额外属性)

    属性标记:

    • tools:remove="attr1,attr2,..." ——删除指定属性
    • tools:replace="attr1,attr2,..." ——替换低优先级清单指定属性为当前清单中的属性
    • tools:strict="attr1,attr2,..." ——当指定属性在低优先级清单与当前清单中不完全一致,触发清单合并错误。是属性合并的默认行为。
    • 支持对同一个元素使用多个标记

    标记选择器:

    • tools:selector="lib1,lib2,..." ——针对某个特定的导入库应用合并规则标记
    • tools:overrideLibrary="lib1,lib2,..." ——替换指定导入库的
      • 默认情况下,导入 minSdkVersion值高于主清单文件的库时会出错,而且无法导入该库。
      • 使用 overrideLibrary,可以保持应用的低 minSdkVersion。

    隐式系统权限

    隐式权限:允许应用在无权限的情况下继续访问特定API,前提是应用的targetSdkVersion设置为低于添加限制的SDK版本的值。

    原则:

    • 如果低优先级清单文件提供隐式权限的 targetSdkVersion值较低,而且高优先级清单没有相同的隐式权限,合并工具将向合并清单显示添加系统权限。

    合并工具可以添加至合并清单的权限列表:

    低优先级清单声明 添加至合并清单的权限
    targetSdkVersion是3或者更低 WRITE_EXTERNAL_STORAGE, READ_PHONE_STATE
    targetSdkVersion是15或者更低,并且使用READ_CONTACTS READ_CALL_LOG
    targetSdkVersion是15或者更低,并且使用WRITER_CONTACTS WRITE_CALL_LOG

    具体合并策略:

    • 合并:将所有非冲突属性合并到同一标记中,然后按其各自的合并策略合并子元素。冲突的属性使用合并规则标记进行合并。
    • 仅合并子项:不整合或合并属性(仅保留高优先级清单文件提供的属性)
    • 保留

    总结

    检查清单合并冲突:在Android Studio中打开AndroidManifest.xml文件,单机编辑器底部的 Merged Manifest选项卡。
    合并策略:通过合并规则标记设置。

  • 相关阅读:
    lambda 是个啥玩意
    python中读写操作plist
    通过os中的os.path.basename获取路径中的文件名
    python遍历目录的两种方法
    mac下已有pyhon2.7,装了python3 之后,怎么调用python3啊
    Python: easy_install & pip 下载PyPi 公共资源库的工具
    安装python的图形处理库: pillow
    minSdkVersion, targetSdkVersion, targetApiLevel,compileSdkVersion,buildToolsVersion
    bat 批量修改文件名字
    a b两向量叉乘 <0说明a在b左边
  • 原文地址:https://www.cnblogs.com/amyzhu/p/9471892.html
Copyright © 2020-2023  润新知