APK拆分配置

来源:互联网 发布:windows telnet 漏洞 编辑:程序博客网 时间:2024/06/04 18:45

虽然你应该尽可能建立一个单一的APK来支持所有的目标设备,这可能会导致用一个非常大的APK处理支持多个屏幕密度或应用二进制接口(ABIs)。 减少APK大小的一种方法是创建多个APK,其中包含特定屏幕密度或ABI的文件。

Gradle使用APK拆分来创建单独的APK,这些APK仅包含特定于每个密度或ABI的代码和资源。 本页介绍如何配置构建来完成APK拆分。 如果您需要创建不基于屏幕密度或ABI的不同版本的应用程序,您可以改用构建变体。

APK拆分配置


要启用APK拆分,请在模块级build.gradle文件中添加一个splits {}块。 在split {}块中,提供一个density {}指定Gradle应如何生成每个密度的APK,或者一个abi {}指定Gradle应如何生成每个ABI的APK。 您可以提供密度和ABI块,构建系统将为每个密度和ABI组合创建一个拆分APK。

配置APK拆分的密度

要为不同的屏幕密度创建单独的APK,请在split {}块中添加density {}块。 在您的density {}块中,提供所需的屏幕密度和兼容的屏幕尺寸的列表。 只有在每个APK的清单中需要特定的<compatible-screens>元素时,才能使用兼容的屏幕尺寸列表。

以下Gradle DSL选项用于配置密度APK拆分:

enable

如果将此元素设置为true,Gradle会根据您定义的屏幕密度生成APK分割。 默认值为false。

exclude

指定一个逗号分隔的密度列表,Gradle不应为其生成单独的APK。 如果您想为大多数密度生成APK,但需要排除应用不支持的几个密度,请使用exclude。

reset()

清除默认的屏幕密度列表。 仅当与include元素组合使用时才能指定要添加的密度。 以下代码片段将密度列表设置为ldpixxhdpi,方法是调用reset()清除列表,然后使用include

reset()  // clear the default list from all densities to no densitiesinclude "ldpi", "xxhdpi" // specify the two densities we want to generate APKs for

include

指定Gradle应生成APK的密度的逗号分隔列表。 只能与reset()结合使用以指定密度的精确列表。

compatibleScreens

指定兼容的屏幕尺寸用逗号分隔的列表。 这将在每个拆分APK的清单中注入匹配的<compatible-screens>节点。 这个可选设置提供了在同一个build.gradle部分管理屏幕密度和屏幕大小的方便方法,但是使用<compatible-screens> 将限制您的应用程序将使用的设备类型。 有关支持不同屏幕大小的其他方法,请参阅支持多个屏幕。


因为基于屏幕密度的拆分的每个APK都包含一个<compatible-screens>标签,其中包含APK支持的屏幕类型的具体限制,即使您发布了多个APK,一些新设备也不会与您的多个APK过滤器匹配。 因此,Gradle总是生成一个额外的通用APK,包含所有屏幕密度的资源,并且不包括<compatible-screens>标记。 您应该发布此通用APK以及拆分APK,以便为与APK不匹配的设备提供后备方案(使用<compatible-screens>标记)。

以下示例为支持的屏幕范围中列出的每个屏幕密度生成单独的APK,除了ldpixxhdpixxxhdpi。 这是通过使用exclude从所有密度的默认列表中删除三个密度来完成的:

android {  ...  splits {    // Configures screen density split settings    density {      // Enables density APK splits      enable true      // Specifies a list of screen densities Gradle should not create APK splits for      exclude "ldpi", "xxhdpi", "xxxhdpi"      // Specifies a list of compatible screen size settings for the manifest      compatibleScreens 'small', 'normal', 'large', 'xlarge'    }  }}

有关密度名称和屏幕尺寸名称的列表,请参阅如何支持多屏幕。 有关将应用程序分发到特定屏幕类型和设备的详细信息,请参阅分发到特定屏幕。

配置APK拆分的ABI

要为不同的ABI创建单独的APK,请在您的split {}块中添加一个abi {}块。 在您的abi {}块中,提供所需ABI的列表。

以下Gradle DSL选项用于配置每ABI APK拆分:

enable

如果将此元素设置为true,Gradle会根据您定义的ABI生成APK拆分。 默认值为false

exclude

指定一个逗号分隔的ABI列表,Gradle不应为其生成单独的APK。 如果您想为大多数ABI生成APK,但需要排除应用程序不支持的几个ABI,请使用exclude

reset()

清除ABI的默认列表。 仅当与include元素组合使用时才指定要添加的ABI。 以下代码片段通过调用reset()将ABI列表设置为x86mips,以清除列表,然后使用include

reset()  // clear the default list from all ABIs to no ABIsinclude "x86", "mips" // specify the two ABIs we want to generate APKs for

include

指定Gradle应为其生成APK的ABI的逗号分隔列表。 只能与reset()结合使用以指定ABI的精确列表。

universalApk

如果为true,Gradle会生成一个通用APK以及拆分APK。 通用APK包含单个APK中所有ABI的代码和资源。 默认值为false。 请注意,此选项仅适用于ABI APK拆分。 密度APK分裂总是生成一个通用的APK,包含所有屏幕密度的代码和资源。


以下示例为每个ABI生成单独的APK:x86,armeabi-v7a和mips。 这是通过使用reset()开始一个空列表的ABI,然后是包含三个ABI列表,每个都将获得一个APK:

android {  ...  splits {    // Configures screen ABI split settings    abi {      // Enable ABI APK splits      enable true      // By default all ABIs are included, so use reset() and include to specify that we only      // want APKs for x86, armeabi-v7a, and mips      // Resets the list of ABIs that Gradle should create APKs for to none      reset()      // Specifies a list of ABIs that Gradle should create APKs for      include "x86", "armeabi-v7a", "mips"      // Specify that we do not want to also generate a universal APK that includes all ABIs      universalApk false    }  }}

有关支持的ABI的列表,请参阅支持的ABI。

配置APK拆分的版本控制

默认情况下,当Gradle生成APK拆分时,每个APK将具有相同的版本信息,如模块级build.gradle文件中指定的。 由于Google Play商店不允许具有相同版本信息的同一应用程序使用多个APK,因此您需要确保每个split APK都有自己独特的versionCode,然后才能上传到Play商店。

您可以配置模块级build.gradle文件以覆盖每个拆分APK的versionCode。 为APK拆分中使用的每个ABI和密度分配唯一的数值,然后使用将·defaultConfig.versionCode·与分配给密度或ABI的数值组合的值覆盖输出版本代码。

以下示例创建一个映射,为每个用于APK拆分的ABI分配唯一的数值。 使用此映射,创建一个每拆分APK版本代码,其将映射的ABI值与defaultConfig.versionCode组合。 在此示例中,x86 ABI的split APK将获得304的versionCode。如果defaultConfig.versionCode重复为5,Gradle将为x86拆分APK分配一个versionCode为305。

android {  ...  defaultConfig {    ...    versionCode 4  }  splits {    ...  }}// map for the version code that gives each ABI a valueext.versionCodes = ['armeabi-v7a':1, mips:2, x86:3]// For each APK output variant, override versionCode with a combination of// ABI APK value * 100 + defaultConfig.versionCodeandroid.applicationVariants.all { variant ->    // assign different version code for each output    variant.outputs.each { output ->        output.versionCodeOverride =                project.versionCodes.get(output.getFilter(OutputFile.ABI)) * 100                + android.defaultConfig.versionCode    }}

有关备用版本代码方案的更多示例,请参阅分配版本代码。

构建APK拆分


配置模块级build.gradle文件以构建APK拆分后,请在Project 窗格单击Build > Build APK为当前选定的模块构建所有APK。 Gradle为每个密度或ABI创建APK在项目的build/outputs/apk/目录下。

Gradle为每个配置的密度或ABI拆分构建一个APK。 如果您为密度和ABI启用了分割,Gradle将为每个密度和ABI组合创建一个APK。 例如,以下build.gradle代码段允许构建mdpi和hdpi密度的APK拆分,以及x86和mips ABI:

...  splits {    density {      enable true      reset()      include "mdpi", "hdpi"    }    abi {      enable true      reset()      include "x86", "mips"    }  }

示例配置的输出将包括以下4个拆分APK:
* app-hdpiX86-release.apk: 仅包含hdpi density和x86 ABI的代码和资源。
* app-hdpiMips-release.apk: 仅包含hdpi密度和mips ABI的代码和资源。
* app-mdpiX86-release.apk: 仅包含mdpi密度和x86 ABI的代码和资源。
* app-mdpiMips-release.apk: 仅包含mdpi密度和mips ABI的代码和资源。

根据您如何配置APK拆分,Gradle还将生成一个通用APK,包含所有密度或ABI的代码和资源。 对于密度APK的拆分,Gradle将始终生成一个通用APK,包括所有密度的代码和资源,除了每个密度的APK。 对于ABI拆分,如果在build.gradle文件中的splits {}块的abi部分中指定universalApk true,Gradle只会生成包含所有ABI的代码和资源的APK。

APK文件名格式

对于APK拆分,Gradle使用APK文件名使用以下方案:
modulename-screendensityABI-buildvariant.apk

方案组件是:

modulename

指定正在构建的模块名称。

screendensity

如果启用屏幕密度APK拆分,则指定APK的屏幕密度,例如“mdpi”。

ABI

如果启用ABI APK拆分,则指定APK的ABI,例如“x86”。 如果屏幕密度和ABI APK拆分都启用,Gradle将密度名称与ABI名称连接,例如“mdpiX86”。 如果为ABI APK分裂启用universalApk,Gradle使用“通用”作为通用APK文件名的ABI部分。

buildvariant

指定正在构建的构建变量,例如“debug”。


例如,对于mdpi屏幕密度启用APK拆分的“myApp”的调试版本将使用APK文件名myApp-mdpi-debug.apk。 发布版本的“myApp”的APK分裂已启用mdpi屏幕密度和x86 ABI将使用APK文件名myApp-mdpiX86-release.apk

1 0
原创粉丝点击