Android App Bundle:动态功能模块

简介: 自 2021 年 8 月起,Google Play 将开始要求新应用使用 Android App Bundle 进行发布。该格式将取代 APK 作为标准发布格式。虽然这个政策目前还无法影响到国内应用,但是作为Android开发者,对于新的动态还是要有一定的认识。本文并不是介绍Android App Bundle,因为它不是新的事物,相关的文章也有很多了,本文重点介绍的是Android App Bundle中“动态功能模块”的实际应用。

前言


自 2021 年 8 月起,Google Play 将开始要求新应用使用 Android App Bundle 进行发布。该格式将取代 APK 作为标准发布格式。虽然这个政策目前还无法影响到国内应用,但是作为Android开发者,对于新的动态还是要有一定的认识。本文并不是介绍Android App Bundle,因为它不是新的事物,相关的文章也有很多了,本文重点介绍的是Android App Bundle中“动态功能模块”的实际应用。


Android App Bundle


Android App Bundle是基于google play的分发技术,可以有效的减少apk的大小。

Android App Bundle可以自动将不同的分辨率、语言、平台(CPU)的资源分别打包,这样当安装时只根据当前设备安装对应的资源,这样大大的节省了内存空间。

除了这些资源,Android App Bundle还支持动态功能模块(Dynamic Feature Module),这样如果用户不需要这部分功能,则不安装这个模块,这样就更加高度优化了下载和安装。


创建动态功能模块


下面就来看看如何创建动态功能模块:

1、从菜单栏中依次选择 File > New > New Module。这一步与创建普通模块一样。

2、在 Create New Module 对话框中,选择 Dynamic Feature Module,然后点击 Next。

网络异常,图片无法展示
|


3、在 Configure your new module 部分中,完成以下操作:

  • 从下拉菜单中选择应用项目的 Base application module。(一般就是main主模块)
  • 指定 Module name。IDE 会使用此名称在 Gradle 设置文件中将该模块标识为 Gradle 子项目。当您构建 app bundle 时,Gradle 会使用子项目名称的最后一个元素在功能模块的清单中注入  属性。
  • 指定该模块的 package name。默认情况下,Android Studio 会建议一个软件包名称,该名称由基本模块的根目录软件包名称和您在上一步中指定的模块名称组合而成。
  • 选择您希望该模块支持的 Minimum API level。此值应与基本模块的值一致。
  • 点击 Next。


4、在 Module Download Options 部分中,完成以下操作:

1)指定最多包含 50 个字符的 Module title。(这个会展示给用户)

2)在 Install-time inclusion 下的下拉菜单中,选择分发时机,有下面三种:

  • Include module at install-time 安装时分发(与普通模块类似)
  • Do not include module at install-time  按需分发(安装时不分发,后面单独说)
  • Only include module at app install for devices with specified features  按条件分发
    按条件分发还需要配置条件,如下图

网络异常,图片无法展示
|


点击“+ device-feature”可以添加一个条件(可以添加多个条件)。在 每个device-feature 旁边,从下拉菜单中选择以下选项之一,然后为其指定值:

  • Name:用于指定设备为在安装应用时下载模块所需具备的硬件或软件功能。按条件分发所支持的功能与被 PackageManager 列为 FEATURE_* 常量的功能相同。如果您选择此选项,请先在下拉菜单旁边的字段中输入相应功能的常量值的任意部分(例如“bluetooth”),然后在所显示的建议中选择一个。
  • OpenGL ES Version:用于指定设备为在安装应用时下载模块所需的 OpenGL ES 版本。如果您选择此选项,请先在下拉菜单旁边的字段中输入相应版本(例如“0x00030001”),然后在所显示的建议中选择一个。


3)如果您希望此模块可提供给搭载 Android 4.4(API 级别 20)及更低版本的设备并包含在多 APK 中,请选中 Fusing 旁边的复选框。这意味着,您可以从不支持下载和安装拆分 APK 的设备上将其省略。

(这部分的配置最终会在模块下的Manifest中体现,下面会提到)


5、点击 Finish即可创建模块


动态功能模块


创建出的模块目录如下:

网络异常,图片无法展示
|


可以看到与正常模块一样,但是这里的Manifest内容有差异,如下:


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="com.huichongzi.dynamicfeature">
    <dist:module
        dist:instant="false"
        dist:title="@string/title_dynamicfeature">
        <dist:delivery>
            <dist:on-demand />
        </dist:delivery>
        <dist:fusing dist:include="true" />
    </dist:module>
</manifest>
复制代码


可以看到这里出现了一个dist标签,这个标签下就是动态功能模块的一些配置。比如dist:instant="false"就是不支持免安装(免安装后面会细说),而title就是上面4步中设置的module title。而


<dist:delivery>
    <dist:on-demand />
</dist:delivery>
复制代码


就是分发时机,on-demand就是Do not include module at install-time即按需分发(后面单独说),如果改成install-time就是Include module at install-time即安装时分发,按条件分发则不太一样,如下:


<dist:delivery>
      <dist:install-time>
          <dist:conditions>
              <dist:device-feature dist:name="android.hardware.camera.ar"/>
              ...
          </dist:conditions>
      </dist:install-time>
  </dist:delivery>
复制代码


模块创建后可以在这里添加新的分发条件。

这里也可以根据国家/地区指定条件


<dist:conditions>
   <!-- Set to "true" to specify countries to exclude from downloading
   this module at app install-time. By default, modules are available
   for download to all user countries. -->
  <dist:user-countries dist:exclude="true">
    <!-- Specifies the two-letter  CLDR country code for regions that should
    not download the module at app install-time. -->
    <dist:country dist:code="CN"/>
    <dist:country dist:code="HK"/>
  </dist:user-countries>
</dist:conditions>
复制代码


根据 API 级别指定条件


<dist:conditions>
    <!-- Specifies the minimum API level that the device must satisfy
         in order to download your module at app install-time. The API level you
         specify must be greater or equal to the module's own minSdkVersion. -->
   <dist:min-sdk dist:value="21"/>
    <!-- Specifies the maximum API level that the device cannot exceed
         in order to download your module at app install-time. The API level you
         specify must be less than or equal to the module's own maxSdkVersion. -->
   <dist:max-sdk dist:value="24"/>
</dist:conditions>
复制代码


与主模块建立关联


当 Android Studio 创建功能模块时,它会自动在基本模块的 build.gradle 文件添加 android.dynamicFeatures 属性,以使该功能模块对基本模块可见,如下所示:


// In the base module’s build.gradle file.
android {
    defaultConfig {
        ...
    }
    ...
    // Specifies feature modules that have a dependency on
    // this base module.
    dynamicFeatures = [":dynamic_feature", ":dynamic_feature2"]
}
复制代码


此外,Android Studio 还会将基本模块添加为功能模块的依赖项,如下所示:


// In the feature module’s build.gradle file:
...
dependencies {
    ...
    // Declares a dependency on the base module, ':app'.
    implementation project(':app')
}
复制代码


部署应用


在开发支持功能模块的应用时,您可以像往常一样,从菜单栏中依次选择 Run > Run(或点击工具栏中的 Run 图标 ),将该应用部署到连接的设备。

如果您的应用项目包含一个或多个功能模块,您可以通过修改现有的运行/调试配置以选择需要在部署应用时包含的功能,具体操作步骤如下:

  • 从菜单栏中依次选择 Run > Edit Configurations。
  • 在 Run/Debug Configurations 对话框的左侧面板中,选择所需的 Android App 配置。
  • 在 General 标签页中的 Dynamic features to deploy 下,选中需要在部署应用时包含的每个功能模块旁边的复选框。
  • 点击 OK。


网络异常,图片无法展示
|


默认情况下,Android Studio 不会使用 app bundle 部署您的应用,而是由 IDE 构建针对部署速度(而非 APK 大小)进行了优化的 APK,并将其安装到设备中。如需将 Android Studio 配置为通过 app bundle 构建和部署 APK 以及免安装体验,请修改运行/调试配置。


按需分发On-Demand


上面我们提到了三种分法模式:安装时分发,按需分发和按条件分发。

安装时分发比较好理解,即在google play下载安装应用的时候就会下载该模块;按条件分发也比较好理解,下载安装应用时,如果当前设备满足条件才会下载该模块;只有按需分发,并不是很容易理解。

按需分发与国内很多应用的插件化类似,就是在功能被使用的时候才会去下载那部分代码和资源。官方描述是这样的:


如果在使用购物平台应用的用户中,只有 20% 的人发布待售商品,有一个不错的策略可以减少大多数用户的初始下载大小,那就是将拍照、输入商品描述及上架商品的功能配置为按需下载。也就是说,您可以为应用的销售功能配置功能模块,使该功能仅在用户希望在购物平台上销售商品时才下载。此外,如果用户在一段时间后不再出售商品,应用可以通过请求卸载该功能减小其安装大小。

developer.android.google.cn/guide/app-b…


但是通过上面创建部署动态模块的流程,我们发现没有关于按需下载的这部分逻辑。这是因为如果要使用动态模块,还需要配合google的play core library才可以:


implementation "com.google.android.play:core:${versions.playcore}"
复制代码


通过这个library中的SplitInstallManager这个类来实现判断模块是否安装,如果没有安装则下载安装等逻辑。

这部分内容很多,受本文篇幅所限就不展开了,官方有一篇很详细的教程:developer.android.com/codelabs/on…有兴趣的同学可以自行阅读(需要梯子)。以后有时间我会单独出一篇中文教程,请大家留意我的公众号更新。


免安装分发


还有一种动态功能模块,即免安装分发。Google Play 免安装体验让用户无需在设备上安装 APK 即可与您的应用互动。用户可以通过 Google Play 商店中的“立即体验”按钮或您创建的网址体验您的应用。这种内容分发形式可让您更轻松地提高用户与应用的互动度。

仅当应用的基本模块也支持免安装体验时,您才能使功能支持免安装体验。这是因为,如果用户想要体验您的应用中某个支持免安装体验的功能模块,他们的设备还必须下载应用的基本模块以获取通用代码和资源。请注意,为了支持 Google Play 免安装体验,基本模块和功能的下载必须满足几个条件:

最大大小:支持免安装体验的基本模块和支持免安装体验的功能模块的总大小不得超过 10 MB。如需了解详情,请阅读通过缩减应用或游戏大小支持免安装体验。

后台活动:支持免安装体验的模块无法使用后台服务。此外,此类模块在后台运行时无法发送通知。

如果您使用 Android Studio 3.5 或更高版本创建支持免安装体验的功能模块(如本部分所述),IDE 会在每个模块的清单中添加以下内容,从而自动使基本模块和功能模块支持免安装体验:


<manifest xmlns:dist="http://schemas.android.com/apk/distribution"
    ... >
    <dist:module dist:instant="true" />
    ...
复制代码


此外,在下载并安装您的应用时,系统会随该应用的基本 APK 自动下载并安装支持免安装体验的功能模块。因此,IDE 还会在支持免安装体验的功能模块中添加以下内容。


<dist:module ...>
        <dist:delivery>
            <dist:install-time />
        </dist:delivery>
    </dist:module>
复制代码


此行为意味着,当您设置 dist:instant="true" 时,不能同时包含<dist:on-demand />。不过,您可以根据需要使用 Play Core 库在免安装体验中请求支持免安装体验的模块。


创建免安装模块

与创建动态模块过程一样,只不过有几处不同:

1、创建选择module类型的时候,选Instant Dynamic Feature Module

2、没有选择分发时机的选项了,所以第四步Module Download Options没有了,剩余的选项合并到第三步Configure your new module中了,所以Configure your new module设置完就finish了。


部署应用


部署与其他动态功能模块一样。


总结


Android App Bundle可以有效的减少安装包体积,而如果利用好动态功能模块(Dynamic Feature Module)更是可以极大的压缩安装包大小,这样可以大幅减少用户下载安装的等待时间,用户可以更快的体验到应用,提高用户的体验。但是动态功能模块(尤其按需分发)一定要设计好,否则用户在使用过程中还要频繁的下载模块也会降低用户体验。


目录
相关文章
|
24天前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
93 4
|
2月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
183 0
安卓项目:app注册/登录界面设计
|
1月前
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码服务器环境配置及app功能
一对一直播源码阿里云服务器环境配置及要求
|
2月前
|
Android开发
Android开发表情emoji功能开发
本文介绍了一种在Android应用中实现emoji表情功能的方法,通过将图片与表情字符对应,实现在`TextView`中的正常显示。示例代码展示了如何使用自定义适配器加载emoji表情,并在编辑框中输入或删除表情。项目包含完整的源码结构,可作为开发参考。视频演示和源码详情见文章内链接。
72 4
Android开发表情emoji功能开发
|
1月前
|
小程序 数据挖掘 UED
开发1个上门家政小程序APP系统,都有哪些功能?
在快节奏的现代生活中,家政服务已成为许多家庭的必需品。针对传统家政服务存在的问题,如服务质量不稳定、价格不透明等,我们历时两年开发了一套全新的上门家政系统。该系统通过完善信用体系、提供奖励机制、优化复购体验、多渠道推广和多样化盈利模式,解决了私单、复购、推广和盈利四大痛点,全面提升了服务质量和用户体验,旨在成为家政行业的领导者。
|
2月前
|
安全 Android开发 iOS开发
Android vs iOS:探索移动操作系统的设计与功能差异###
【10月更文挑战第20天】 本文深入分析了Android和iOS两个主流移动操作系统在设计哲学、用户体验、技术架构等方面的显著差异。通过对比,揭示了这两种系统各自的独特优势与局限性,并探讨了它们如何塑造了我们的数字生活方式。无论你是开发者还是普通用户,理解这些差异都有助于更好地选择和使用你的移动设备。 ###
54 3
|
3月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
148 15
一个Android App最少有几个线程?实现多线程的方式有哪些?
|
1月前
|
机器人
布谷直播App系统源码开发之后台管理功能详解
直播系统开发搭建管理后台功能详解!
|
3月前
|
移动开发 Android开发 数据安全/隐私保护
移动应用与系统的技术演进:从开发到操作系统的全景解析随着智能手机和平板电脑的普及,移动应用(App)已成为人们日常生活中不可或缺的一部分。无论是社交、娱乐、购物还是办公,移动应用都扮演着重要的角色。而支撑这些应用运行的,正是功能强大且复杂的移动操作系统。本文将深入探讨移动应用的开发过程及其背后的操作系统机制,揭示这一领域的技术演进。
本文旨在提供关于移动应用与系统技术的全面概述,涵盖移动应用的开发生命周期、主要移动操作系统的特点以及它们之间的竞争关系。我们将探讨如何高效地开发移动应用,并分析iOS和Android两大主流操作系统的技术优势与局限。同时,本文还将讨论跨平台解决方案的兴起及其对移动开发领域的影响。通过这篇技术性文章,读者将获得对移动应用开发及操作系统深层理解的钥匙。
|
3月前
|
存储 开发工具 Android开发
使用.NET MAUI开发第一个安卓APP
【9月更文挑战第24天】使用.NET MAUI开发首个安卓APP需完成以下步骤:首先,安装Visual Studio 2022并勾选“.NET Multi-platform App UI development”工作负载;接着,安装Android SDK。然后,创建新项目时选择“.NET Multi-platform App (MAUI)”模板,并仅针对Android平台进行配置。了解项目结构,包括`.csproj`配置文件、`Properties`配置文件夹、平台特定代码及共享代码等。
260 2