Android App Bundle是一种改进的应用程序打包方式,能大幅度减少应用体积。简而言之,可以理解Google 官方的动态发布方案。
好处
Size更小
- Google has claimed that it can reduce app sizes up to 50 percent
- Its own apps like YouTube and other apps like LinkedIn which saw a 23% file reduction
- 安装更快
- 支持动态发布
限制
- 仅限于通过 Google Play 发布的应用,(Google进一步巩固自身生态)
- 需要加入到 Google 的 beta program enroll your app in app signing by Google Play in the Play Console
- 最低支持版本Android 5.0 (API level 21)
- 低于Android 5.0 (API level 21) 的版本GooglePlay会优化Size,但不支持动态交付。
成本
- 需要升级到Android Studio 3.2修改工程以便支持App Bundle格式
- 集成Play Core Library
原理
只须在 Android Studio 中构建一个应用束 (app bundle),就可以将应用所需的全部内容 (适用于所有设备) 都涵盖在内:所有语言、所有设备屏幕大小、所有硬件架构。接着,在用户下载您的应用时,Google Play 的新动态交付只会传输适用于用户设备的代码和资源。人们在 Play Store 上看到的安装包体积更小,下载速度也越快,同时也节省了设备存储空间。
- (左)旧版 APK 交付样例 - 将全部资源都交付至设备;
- (右) 动态交付样例 - 只向设备交付必要资源;
结合Google Play Dynamic Delivery (动态交付) , 实现动态功能
Android App Bundle 支持模块化,通过Dynamic Delivery with split APKs,将一个apk拆分成多个apk,按需加载(包括加载C/C++ libraries),这样开发者可以随时按需交付功能,而不是仅限在安装过程中。
- Base Apk
首次安装的apk,公共代码和资源,所以其他的模块都基于Base Apk - Configuration APKs
native libraries 和适配当前手机屏幕分辨率的资源 -
Dynamic feature APKs
不需要在首次安装就加载的模块
使用方法
app模块为Base Apk,features目录下的模块为Dynamic feature APKs。Base Apk和正常的Android应用项目一样,它决定了最终程序的版本号、应用签名、代码缩小、splits、包名等信息。
默认情况下,在构建应用程序包时,它支持为每组语言资源,屏幕密度资源和ABI库生成配置APK。使用android.bundle基本模块build.gradle文件中的块 ,如下所示,您可以禁用对一种或多种配置APK的支持:
android {
// When building Android App Bundles, the splits block is ignored.
splits {...}
// Instead, use the bundle block to control which types of configuration APKs
// you want your app bundle to support.
bundle {
language {
// Specifies that the app bundle should not support
// configuration APKs for language resources. These
// resources are instead packaged with each base and
// dynamic feature APK.
enableSplit = false
}
density {
// This property is set to true by default.
enableSplit = true
}
abi {
// This property is set to true by default.
enableSplit = true
}
}
}
Dynamic feature APKs是需要动态加载的模块,如果手机不支持动态加载,其内容会合并到最终的apk内。
创建动态功能模块
创建新动态功能模块的最简单方法是使用Android Studio 3.2或更高版本。由于动态要素模块对基础应用程序模块具有内在依赖性,因此您只能将它们添加到现有应用程序项目中。
要使用Android Studio向您的应用项目添加动态功能模块,请执行以下操作:
- 如果您还没有这样做,请在IDE中打开您的应用程序项目。
- 从菜单栏中选择File> New> New Module。
- 在Create New Module对话框中,选择 Dynamic Feature Module,然后单击Next。
- 在“ 配置新模块”部分中,完成以下操作:
a. 从下拉菜单中选择应用程序项目的Base应用程序模块。
b. 指定模块名称。IDE使用此名称将模块标识为Gradle设置文件中的Gradle子项目 。构建应用程序包时,Gradle使用子项目名称的最后一个元素将<manifest split>属性 注入AndroidManifest清单中。
c. 指定模块的包名称。默认情况下,Android Studio会建议一个包名称,该名称包含基本模块的根包名称和您在上一步中指定的模块名称。
d. 选择希望模块支持的最低API级别。该值应与基本模块的值匹配。 - 单击下一步。
- 在“ 配置按需选项”部分中,执行如下操作:
a. 使用最多50个字符指定模块标题。例如,当确认用户是否想要下载模块时,平台使用该标题来向用户标识模块。因此,您的应用程序的基本模块必须包含模块标题作为字符串资源,您可以将其翻译。使用Android Studio创建模块时,IDE会为您将字符串资源添加到基本模块,并在动态要素模块的清单中注入以下条目:
<dist:module
...
dist:title="@string/title_dynamic_feature">
</dist:module>
b. 如果希望模块可用于按需下载,请选中“ 按需启用 ”旁边的框。如果您未启用此选项,则当用户首次下载并安装您的应用时,可以使用动态功能。Android Studio会在模块的清单中注入以下内容以反映您的选择。
<dist:module
...
dist:onDemand="true">
</dist:module>
c. 如果您希望此模块可供运行Android 4.4(API级别20)及更低版本的设备使用,请选中“ 融合 ”旁边的框,并将其包含在多个APK中。仅当您选中上一步中按需启用旁边的框时,此选项才可用。这意味着您可以为此模块启用按需行为,并禁用融合以从不支持下载和安装拆分APK的设备中省略它。Android Studio会在模块的清单中注入以下内容以反映您的选择。
<dist:module
...
<dist:fusing dist:include="true" />
</dist:module>
- 单击完成。
在Android Studio完成模块创建后,请从“ 项目”窗格中自行检查其内容( 从菜单栏中选择“ 视图”>“工具窗口”>“项目 ”)。您应该快速注意到默认代码,资源和组织与标准应用程序模块的默认代码,资源和组织类似。
动态功能模块构建配置
使用Android Studio创建新的动态要素模块时,IDE会将以下Gradle插件应用于模块的build.gradle
文件。
// The following applies the dynamic-feature plugin to your dynamic feature module.// The plugin includes the Gradle tasks and properties required to configure and build// an app bundle that includes your dynamic feature module.apply plugin: 'com.android.dynamic-feature'
什么不包括在动态功能模块构建配置中
由于每个动态功能模块都依赖于基本模块,因此它还会继承某些配置。因此,您应该在动态要素模块的build.gradle
文件中省略以下内容:
- 签名配置:使用您在基本模块中指定的签名配置对应用程序包进行签名。
-
该
minifyEnabled
属性:您可以 使代码萎缩 仅从基本模块的构建配置为您的整个应用项目。因此,您应该从动态功能模块中省略此属性。但是,您可以 为每个动态要素模块指定其他ProGuard规则。 -
versionCode
和versionName
:构建应用程序包时,Gradle使用基本模块提供的应用程序版本信息。您应该从动态模块的build.gradle
文件中省略这些属性 。
建立与基础模块的关系
当Android Studio创建动态要素模块时,通过将android.dynamicFeatures
属性添加到基础模块的build.gradle
文件,它使基本模块可见,如下所示:
// In the base module’s build.gradle file.android { ... // Specifies dynamic feature modules that have a dependency on // this base module. dynamicFeatures = [":dynamic-feature", ":dynamic-feature2"]}
此外,Android Studio将基本模块作为动态功能模块的依赖项,如下所示:
// In the dynamic feature module’s build.gradle file:...dependencies { ... // Declares a dependency on the base module, ':app'. implementation project(':app')}
指定其他ProGuard规则
虽然只有基本模块的构建配置可以为您的应用项目启用代码缩减,但可以使用proguardFiles属性为每个动态功能模块提供自定义ProGuard规则 ,如下所示。
android.buildTypes {
release {
// You must use the following property to specify additional ProGuard
// rules for dynamic feature modules.
proguardFiles 'proguard-rules-dynamic-features.pro'
}
}
部署您的应用
在开发支持动态交付的应用程序时,可以像往常一样通过从菜单栏选择“运行”>“运行”(或单击工具栏中的“运行 ),将应用程序部署到连接的设备 。
附:谷歌官方示例 https://github.com/googlesamples/android-dynamic-features