About Dynamic Delivery

    Most app projects won’t require much effort to build app bundles that supportserving optimized . For example,if you already organize your app’s code andresourcesaccording to established conventions, simply using Android Studio or usingthe command line, and . Dynamic Delivery then becomes an automaticbenefit.

    To support advanced capabilities of Dynamic Delivery, such as configuringcertain features of your app to be delivered conditionally or downloaded ondemand, read the section on how to customize featuredelivery.

    A fundamental component of Dynamic Delivery is the split APK mechanismavailable on Android 5.0 (API level 21) and higher. Split APKs are verysimilar to regular APKs—they include compiled DEX bytecode, resources, and anAndroid manifest. However, the Android platform is able to treat multipleinstalled split APKs as a single app. That is, you can install multiple splitAPKs that have access to common code and resources, and appear as oneinstalled app on the device.

    The benefit of split APKs is the ability to break up a monolithic APK—that is,an APK that includes code and resources for all features and deviceconfigurations your app supports—into smaller, discrete packages that areinstalled on a user’s device as required.

    For example, one split APK may include the code and resources for anadditional feature that only a few of your users need, while another split APKincludes resources for only a specific language or screen density. Each ofthese split APKs is downloaded and installed when the user requests itor it’s required by the device.

    The following describes the different types of APKs that may be installedtogether on a device to form your full app experience. You’ll learn how toconfigure your app project to support these APKs in later sections on this page.

    • Base APK: This APK contains code and resources that all other splitAPKs can access and provides the basic functionality for your app. When auser requests to download your app, this APK is downloaded and installedfirst. That’s because only the base APK’s manifest contains a fulldeclaration of your app’s services, content providers,permissions, platform version requirements, and dependencies on systemfeatures. Google Play generates the base APK for your app from yourproject’s app (or base) module. If you are concerned with reducing your app’sinitial download size, it’s important to keep in mind that all code andresources included in this module are included in your app’s base APK.
    • Configuration APKs: Each of these APKs includes native libraries andresources for a specific screen density, CPU architecture, or language.When a user downloads your app, their device downloads and installs onlythe configuration APKs that target their device. Each configuration APKis a dependency of either a base APK or dynamic feature APK. That is,they are downloaded and installed along with the APK they provide codeand resources for. Unlike the base and dynamic feature modules, you don'tcreate a separate module for configuration APKs. If you use standard practicesto for your base and dynamic feature modules, Google Play automaticallygenerates configuration APKs for you.
    • Dynamic feature APKs: Each of these APKs contains code and resources for afeature of your app that you modularize using dynamic feature modules. ThroughDynamic Delivery, you can then customize how and when that feature is downloadedonto a device. For example, using the Play CoreLibrary, dynamic APKsmay be installed on demand after the base APK is installed on the device toprovide additional functionality to the user. Consider a chat app that downloadsand installs the ability to capture and send photos only when the user requeststo use that functionality. Because dynamic features may not be available atinstall time, you should include any common code and resources in the base APK.That is, your dynamic feature should assume that code and resources of only thebase APK are available at install time. Google Play generates dynamic featureAPKs for your app from your project’s dynamic feature modules.
      Consider an app with three dynamic feature modules and support for multipledevice configurations. Figure 1 below illustrates what the dependency tree forthe app’s various APKs may look like. Note that the base APK forms the head ofthe tree, and all other APKs depend on the base APK. (If you're curious abouthow the modules for these APKs are represented in an Android App Bundle,see .)

    Keep in mind, you don’t need to build these APKs yourself—Google Play does itfor you using a single signed app bundle you build with Android Studio. Tolearn more about the app bundle format and how to build one, go toBuild, deploy, and upload Android App Bundles.

    Because devices running Android 4.4 (API level 19) and lower don’t supportdownloading and installing split APKs, Google Play instead serves thosedevices a single APK, called a multi-APK, that’s optimized for the device'sconfiguration. That is, multi-APKs represent your full app experience but do notinclude unnecessary code and resources—such as those for other screen densitiesand CPU architectures.

    They do, however, include resources for all languages thatyour app supports. This allows, for example, users to change your app'spreferred language setting without having to download a different multi-APK.

    Multi-APKs do not have the ability to later download dynamic features moduleson demand. To include a dynamic module in this APK, you must either disableOn-demand or enable Fusing when.

    Keep in mind, with Dynamic Delivery, you don't need to build, sign,upload, and manage APKs for each device configuration your app supports. Youstill build and upload only a single app bundle for your entire app, and GooglePlay takes care of the rest for you. So whether or not you plan to supportdevices running Android 4.4 or lower, Dynamic Delivery provides a flexibleserving mechanism for both you and your users.

    Modularize your app

    Modularizing your app is the process of separating logical components of yourapp project into discrete modules.

    Reorganizing your app’s functionality into these discrete components takescareful consideration and time. However, modularization provides your projectwith the following benefits:

    • Develop in parallel: By separating logical components of your app intomodules, different teams or individuals in your organization can take ownershipof each module and work on them with fewer merge conflicts or disruptions toother teams. Additionally, if you have logic that’s used in various parts ofyour app, you can use library modules) to promote code reuse andencapsulation.
    • Improve build times: Build systems, such as the Android Studio buildsystem using Gradle, are optimized for projects that are organized intomodules. For example, if you enable Gradle’s optimization on a workstation includes a multi-core processor, the buildsystem is able to build multiple modules in parallel and significantlyreduce build times. The more modular your project is, the more significantthe build performance improvement becomes.
    • Customize feature delivery: Modularizing your app’s features as dynamicfeature modules is a requirement to take advantage of Dynamic Delivery’s customdelivery options, such as on demand, conditional, andinstant delivery. Creating on demand dynamic features requires more effort andpossible refactoring of your app. So, consider carefully which of your app’sfeatures would benefit the most from being modularized into dynamic featuresand benefiting from custom delivery options.
      Modularizing your project by app features takes time and consideration to doproperly. When you do decide to begin modularizing your app, you should firstwith the properties necessary to support modular features. Then, you cangradually modularize your app’s features without changing the current behaviorof your app by configuring dynamic feature modules for at-installdelivery.

    Although you get highly optimized downloads by default when you upload your appas an app bundle, the more advanced and customizable feature delivery optionsrequire additional configuration and modularization of your app’s features usingdynamic feature modules. That is, dynamic feature modules provide the buildingblocks for creating modular features that you can configure to each bedownloaded as needed.

    Consider an app that allows your users to buy and sell goods in an onlinemarketplace. You can reasonably modularize each of the following functionalitiesof the app into separate dynamic feature modules:

    • Account login and creation
    • Browsing the marketplace
    • Placing an item for sale
    • Processing payments
      The table below describes the different delivery options that dynamic featuremodules support, and how they might be used to optimize the initial downloadsize of the sample marketplace app.

    When creating a new dynamic feature module using Android Studio, the IDEincludes most of the manifest attributes that the module requires to behavelike a dynamic feature. Additionally, some attributes are injected by thebuild system at compile time, so you needn’t specify or modify them yourself.The following table describes the manifest attributes that are important todynamic feature modules.

    AttributeDescription
    This is your typical block.
    xmlns:dist="http://schemas.android.com/apk/distribution"Specifies a new dist: XML namespace that’s described further below.
    split="splitname" When Android Studio builds your app bundle, it includes this attribute for you. So, you should not include or modify this attribute yourself.
    Defines the name of the module, which your app specifies when requesting an on demand module using the Play Core Library.

    How Gradle determines the value for this attribute:

    By default, when you create a dynamic feature module using Android Studio, The IDE uses what you specify as its Module name to identify the module as a Gradle subproject in your .

    When you build your app bundle, Gradle uses the last element of the subproject path to inject this manifest attribute in the module’s manifest. For example, if you create a new dynamic feature module in the MyAppProject/features/ directory and specified "dynamic_feature1" as its Module name, the IDE adds ':features:dynamic_feature1' as a subproject in your settings.gradle file. When building your app bundle, Gradle then injects <manifest split="dynamic_feature1"> in the module’s manifest.
    android:isFeatureSplit="true | false"> When Android Studio builds your app bundle, it includes this attribute for you. So, you should not include or modify this attribute manually.
    Specifies that this module is a dynamic feature module. Manifests in the base module and configuration APKs either omit this attribute or set it to .
    <dist:moduleThis new XML element defines attributes that determine how the module is packaged and distributed as APKs.
    dist:instant="true | false" Specifies whether the module should be available through Google Play Instant as an instant experience.
    If your app includes one or more instant-enabled dynamic feature modules, you must also instant-enable the base module. When using Android Studio 3.3 or higher, the IDE does this for you when you .

    You can’t set this XML element to true while also setting dist:onDemand="true". However, you can still request on demand downloads of your instant-enabled dynamic features _as instant experiencesusing the Play Core Library. When a user downloads and installs your app, the device downloads and installs your app's instant-enabled dynamic features, along with the base APK, by default.
    dist:onDemand="true | false" Specifies whether the module should be available as an on demand download. That is, if this attribute is set to true, the module is not available at install time, but your app may request to download it later.
    If this attribute is set to false, the module is included when the user first downloads and installs your app.

    To learn more about on demand downloads, read about .
    dist:title="@string/feature_name" Specifies a user-facing title for the module. For example, the device may display this title when it requests download confirmation.
    You need to include the string resource for this title in the base module’s module_root/src/source_set/res/values/strings.xml file.
    Specifies whether to include the module in multi-APKs that target devices running Android 4.4 (API level 20) and lower.
    Additionally, when you use bundletool to generate APKs from an app bundle, only dynamic feature modules that set this property to true are included in the universal APK—which is a monolithic APK that includes code and resources for all device configurations your app supports.
    <application


    ="true | false">



    </application>
    If the dynamic feature module generates no DEX files—that is, it contains no code that is later compiled into the DEX file format—you must do the following (otherwise, you may get runtime errors):
    - Set android:hasCode to "false" in the dynamic feature module's manifest.
    - Add the following to your base module's manifest:



    Note: Dynamic feature modules should not specify activities in their manifest withandroid:exported set totrue. That's because there's no guarantee that the devicehas downloaded the dynamic feature module when another app tries to launch theactivity. Additionally, your app should confirm that a dynamic feature isdownloaded before trying to access its code and resources. To learn more, read.

    Test Dynamic Delivery

    The best way to test Dynamic Delivery is through the Google Play Store. That'sbecause a lot of the benefits of Dynamic Delivery rely on deferring optimizedAPK generation, signing, and serving to the Play Store. So, whether youinclude basic support for Dynamic Delivery by uploading an app bundle orconfigure custom delivery options, you should use the following methods to testyour app with Dynamic Delivery"

    If you want to publish an app that includes dynamic feature modules to aproduction track, keep the following considerations in mind:

    • Only devices running Android 5.0 (API level 21) and higher supportdownloading and installing dynamic features on demand. To make your dynamicfeature available to earlier versions of Android, make sure to enableFusing when you create a dynamic feature module.
    • Make sure you,so that your app has immediate access to downloaded dynamic feature modules.
    • If the download size for your dynamic feature is large, your app needs toobtain user confirmationbefore it can download the dynamic feature module to a device.
    • Dynamic feature modules should not specify activities in their manifest with set totrue. That's because there's no guarantee that the devicehas downloaded the dynamic feature module when another app tries to launch theactivity. Additionally, your app should confirm that a dynamic feature isdownloaded before trying to access its code and resources. To learn more, readManage installed modules.
    • Because dynamic delivery requires you to publish your app using an app bundle,make sure that you're aware of app bundle.

    Additional resources

    To learn more about using supporting Dynamic Delivery, try the followingresource.

    • PlayCore API sample,a sample app that demonstrates usage of the PlayCore API to request anddownload dynamic features.