android app bundle Split APKs

android app bundle Split APKs

BaseApk:该APK包含所有其他拆分APK都可以访问的代码和资源,并为您应用程序提供基本功能。当用户请求下载您的应用程序时,首先下载并安装该APK。这是因为只有BaseAPK的manifest 包含应用程序的services、content providers、premissions、platform version 和对系统特性的依赖的完整声明。谷歌Play从项目的app(或base)模块为应用程序生成基本APK。如果您想要减小应用程序的初始下载大小,那么一定要记住,此模块中包含的所有代码和资源都包含在应用程序的基本APK中。

 

Configuration APKs:每个apk都包含针对特定屏幕密度、CPU架构或语言的本机库和资源。当用户下载您的应用程序时,他们的设备只下载并安装针对其设备的配置apk。每个配置APK都是Base APK或 dynamic feature APK的依赖项。也就是说,它们与它们提供代码和资源的APK一起下载和安装。与基本功能模块和动态功能模块不同,您不需要为配置apk创建单独的模块。如果您使用标准实践为基本功能模块和动态功能模块组织可选的、特定于配置的资源,谷歌Play将自动为您生成配置apk。

 

Dynamic feature APKs:您可以自定义如何以及何时将该功能下载到设备上。例如,使用Play Core库,可以在设备上安装base APK之后根据需要安装动态APK以向用户提供额外的功能。考虑一个聊天应用程序,它可以下载并安装只在用户请求使用该功能时才能捕获和发送照片的功能。因为动态特性在安装时可能不可用,所以应该在BseeAPK中包含任何公共代码和资源。也就是说,您的动态特性应该假设只有基本APK的代码和资源在安装时可用。谷歌Play从项目的动态功能模块为应用程序生成动态功能apk。

 

Apks 依赖关系:

 

 

这些apk在gradle构建时自动生成。

 

在4.4以下系统支持

由于运行Android 4.4 (API级别19)及以下的设备不支持下载和安装split APK,因此谷歌Play为这些设备提供一个名为multi-APK的APK,该APK针对设备的配置进行了优化。也就是说,多apk代表了您完整的应用程序体验,但不包含不必要的代码和资源——例如用于其他屏幕密度和CPU架构的代码和资源。

但是,它们包含应用程序支持的所有语言的资源。例如,这允许用户更改应用程序的首选语言设置,而无需下载不同的multi-APK。

多apk没有能力在以后按需下载动态特性模块。要在这个APK中包含一个动态模块,您必须在创建动态特性模块时禁用随需应变或启用融合。

 

模块化

模块化应用程序是将应用程序项目的逻辑组件分离为离散模块的过程。

将应用程序的功能重新组织到这些离散组件中需要仔细考虑和时间。

模块化好处:

1.并行开发:通过将应用程序的逻辑组件分离到模块中,组织中的不同团队或个人可以拥有每个模块,并处理它们,从而减少对其他团队的合并冲突或中断。此外,如果您的应用程序的各个部分都使用了逻辑,那么您可以使用库模块来促进代码重用和封装。

2.提升构建时间:构建系统,例如使用Gradle的Android Studio构建系统,针对组织成模块的项目进行了优化。例如,如果您在一个包含多核处理器的工作站上启用Gradle的并行项目执行优化,那么构建系统就能够并行地构建多个模块,从而显著减少构建时间。您的项目越模块化,构建性能的改进就越重要。

3.定制特性交付:将应用程序的特性模块化为动态特性模块是利用动态交付的定制交付选项(如随需应变、有条件交付和即时交付)的必要条件。创建随需应变的动态特性需要付出更多的努力,并可能对应用程序进行重构。因此,请仔细考虑哪些应用程序特性将从模块化为动态特性和自定义交付选项中获益最多。

通过应用程序特性模块化您的项目需要时间和适当的考虑。当您决定开始模块化您的应用程序时,您应该首先使用支持模块化特性所需的属性来配置base module。然后,您可以通过为at-install交付配置动态特性模块,逐步模块化应用程序的特性,而无需更改应用程序的当前行为。

 

使用动态特性模块进行自定义交付

动态交付的一个独特好处是能够定制应用程序的不同功能如何以及何时下载到运行Android 5.0 (API级别21)或更高的设备上。例如,为了减小应用程序的初始下载大小,您可以配置某些功能,以便根据需要下载,或者只由支持某些功能的设备下载,比如拍照功能或支持增强现实功能。

虽然默认情况下,当您将应用程序作为应用程序包上载时,您可以获得高度优化的下载,但是更高级和可定制的功能交付选项需要使用动态功能模块对应用程序的功能进行额外配置和模块化。也就是说,动态特性模块为创建模块化特性提供了构建块,您可以根据需要将其配置为每个模块。

 

考虑一个允许用户在在线市场上买卖商品的应用程序。您可以合理地将应用程序的以下功能模块化为单独的动态功能模块

帐号登录及创建

浏览市场

出售物品

处理付款

下表描述了动态特性模块支持的不同交付选项,以及如何使用它们优化示例marketplace应用程序的初始下载大小。

交付选项 行为 样本用例
At-install 
安装时
默认情况下,不配置上述任何交付选项的动态特性模块在app安装时下载。这是一个重要的行为,因为它意味着您可以逐步采用高级交付选项。例如,只有在使用Play Core库完全实现了按需下载之后,您才能从模块化应用程序的功能中获益,并启用随需应变交付功能。

此外,您的应用程序可以请求卸载功能在稍后的时间。所以,如果你在app安装时需要某些功能,但在那之后就不需要了,你可以通过请求从设备上移除该功能来减小安装尺寸。
如果应用程序有特定的培训活动,比如关于如何在市场上买卖商品的交互式指南,默认情况下,您可以在应用程序安装时包含该功能。

但是,为了减小app的安装尺寸,app可以在用户完成培训后请求删除该功能。
On demand 
按需
允许您的应用程序根据需要请求和下载动态功能模块。 如果只有20%的人使用市场上应用物品出售,一个好的策略来减少初始下载大小对大多数用户来讲是让拍照的功能,包括一个项目的描述,和把一个项目销售提供按需下载。也就是说,您可以为应用程序的销售功能配置动态特性模块,只有当用户对将商品放到市场上感兴趣时,才可以下载该应用程序的销售功能。

此外,如果用户在一段时间后不再出售商品,应用程序可以通过要求卸载该功能来缩小其安装的大小。
Conditional  
有条件的
允许您指定特定的用户设备需求,例如硬件特性、区域设置和最低API级别,以确定是否在app安装时下载模块化特性。 如果市场应用程序具有全球性,您可能需要支持仅在某些地区或本地流行的支付方法。为了减少最初的应用程序下载大小,您可以创建单独的动态功能模块来处理某些类型的支付方法,并根据用户的注册地区有条件地将它们安装在用户的设备上。
Instant
即时的
谷歌Play Instant允许用户在不需要在设备上安装APK(s)的情况下与您的应用程序进行交互。相反,他们可以通过谷歌Play Store上的“立即尝试”按钮或您创建的URL体验您的应用程序。这种交付内容的形式使您更容易增加与应用程序的接触。

通过即时交付,您可以利用谷歌Play instant让您的用户无需安装就可以立即体验应用程序的某些功能。
考虑一个在轻量级动态特性模块中包含游戏最初几个级别的游戏。你可以立即启用该模块,这样用户就可以通过URL链接或“立即尝试”按钮来体验游戏,而无需安装应用程序。

 

Dynamic feature module manifest

当使用Android Studio创建一个新的动态特性模块时,IDE包含了该模块作为动态特性所需要的大部分显式属性。此外,一些属性是编译时由构建系统注入的,所以您不需要自己指定或修改它们。下表描述了对动态特性模块非常重要的清单属性。

 

属性 描述
<manifest
...
 
xmlns:dist="http://schemas.android.com/apk/distribution" 指定一个新的dist: XML名称空间,将在下面进一步描述。
split="split_name" 当Android Studio构建应用程序包时,它会为您包含这个属性。因此,您不应该自己包含或修改这个属性。
定义模块的名称,应用程序在使用Play Core库请求随需应变模块时指定该名称。
Gradle如何确定这个属性的值:
默认情况下,当您使用Android Studio创建动态特性模块时,IDE使用您指定的模块名称来标识模块为Gradle设置文件中的Gradle子项目。
在构建应用程序包时,Gradle使用子项目路径的最后一个元素将这个manifest属性注入模块的manifest中。例如,如果在MyAppProject/features/目录中创建一个新的动态特性模块,并指定“dynamic_feature1”作为模块名,IDE就会在设置中添加“:features:dynamic_feature1”作为子项目。gradle文件。在构建应用程序包时,Gradle会在模块的清单中注入。
android:isFeatureSplit="true |false"> 当Android Studio构建应用程序包时,它会为您包含这个属性。因此,不应该手动包含或修改此属性。
指定此模块为动态特性模块。基本模块和配置apk中的Manifest要么省略该属性,要么将其设置为false。
<dist:module 这个新的XML元素定义了一些属性,这些属性决定如何将模块打包并作为apk分发。
dist:instant="true | false" 指定模块是否应该通过谷歌Play Instant作为即时体验提供。
如果您的应用程序包含一个或多个即时启用的动态功能模块,您还必须即时启用基本模块。当使用Android Studio 3.5或更高版本时,当您创建一个即时启用的动态特性模块时,IDE会为您完成这一任务。
在同时设置时,不能将此XML元素设置为true。不过,您仍然可以使用Play Core库按需下载即时启用的动态特性,作为即时体验。当用户下载并安装您的应用程序时,默认情况下,设备会下载并安装您的应用程序的即时启用动态特性,以及基本的APK。
dist:title="@string/feature_name" 为模块指定一个面向用户的标题。例如,当设备请求下载确认时,它可能会显示这个标题。
您需要在基本模块的module_root/src/source_set/res/values/strings.xml文件中包含这个标题的字符串资源。
<dist:fusing dist:include="true |false" /> 
</dist:module>
指定是否将模块包含在针对运行Android 4.4 (API级别20)及以下设备的多apk中。
此外,当您使用bundletool从应用程序包生成APK时,只有将此属性设置为true的动态特性模块才包含在universal APK中——这是一个独立的APK,包含应用程序支持的所有设备配置的代码和资源。
<dist:delivery> 封装定制模块交付的选项,如下所示。请记住,每个动态特性模块只能配置这些自定义交付选项的一种类型。
<dist:install-time/> 指定模块应在安装时可用。这是不指定另一种类型的自定义交付选项的动态特性模块的默认行为。
此节点还可以指定将模块限制为满足特定需求的设备的条件,例如设备特性、用户国家或最低API级别。要了解更多信息,请阅读Configure conditional delivery。
<dist:on-demand/> 指定模块应可随需下载。也就是说,模块在安装时不可用,但是您的应用程序稍后可能会请求下载它。
</dist:delivery>  
<application 
android:hasCode="true | false"> 
... 
</application>
如果动态特性模块没有生成DEX文件——也就是说,它不包含后来编译成DEX文件格式的代码——您必须执行以下操作(否则,您可能会得到运行时错误):
1.在动态特性模块的清单中将android:hasCode设置为“false”。
2.将以下内容添加到基本模块的清单中:
<span style="color:#000000"><span style="color:#37474f"><span style="color:#3b78e7"><application</span>
  <span style="color:#9c27b0">android:hasCode</span>=<span style="color:#0d904f">"true"</span>
  <span style="color:#9c27b0">tools:replace</span>=<span style="color:#0d904f">"android:hasCode"</span><span style="color:#3b78e7">></span>
  ...
<span style="color:#3b78e7"></application></span></span></span>

动态特性模块不应该在其清单中指定android: exports设置为true的活动。这是因为,当其他应用程序试图启动活动时,无法保证设备已经下载了动态功能模块。此外,在尝试访问其代码和资源之前,应用程序应该确认下载了动态特性。

上一篇:如何下载Google Play商店的apk?如何安装分割的apk ?


下一篇:CSP 后多校九