About Dynamic Delivery

Google Play’s app serving model, called Dynamic Delivery, uses Android App
Bundles to generate and serve optimized APKs for each user’s
device configuration, so users download only the code and resources they need to
run your app. You no longer have to build, sign, and manage multiple APKs to
support different devices, and users get smaller, more optimized downloads.

To support advanced capabilities of Dynamic Delivery, such as configuring
certain features of your app to be delivered conditionally or downloaded on
demand, read the section on how to customize feature
delivery.

Dynamic Delivery with split APKs

A fundamental component of Dynamic Delivery is the split APK mechanism
available on Android 5.0 (API level 21) and higher. Split APKs are very
similar to regular APKs—they include compiled DEX bytecode, resources, and an
Android manifest. However, the Android platform is able to treat multiple
installed split APKs as a single app. That is, you can install multiple split
APKs that have access to common code and resources, and appear as one
installed 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 device
configurations your app supports—into smaller, discrete packages that are
installed on a user’s device as required.

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

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

Base APK: This APK contains code and resources that all other split
APKs can access and provides the basic functionality for your app. When a
user requests to download your app, this APK is downloaded and installed
first. That’s because only the base APK’s manifest contains a full
declaration of your app’s services, content providers,
permissions, platform version requirements, and dependencies on system
features. Google Play generates the base APK for your app from your
project’s app (or base) module. If you are concerned with reducing your app’s
initial download size, it’s important to keep in mind that all code and
resources included in this module are included in your app’s base APK.

Configuration APKs: Each of these APKs includes native libraries and
resources for a specific screen density, CPU architecture, or language.
When a user downloads your app, their device downloads and installs only
the configuration APKs that target their device. Each configuration APK
is a dependency of either a base APK or dynamic feature APK. That is,
they are downloaded and installed along with the APK they provide code
and resources for. Unlike the base and dynamic feature modules, you don't
create a separate module for configuration APKs. If you use standard practices
to organize alternative, configuration-specific resources
for your base and dynamic feature modules, Google Play automatically
generates configuration APKs for you.

Dynamic feature APKs: Each of these APKs contains code and resources for a
feature of your app that you modularize using dynamic feature modules. Through
Dynamic Delivery, you can then customize how and when that feature is downloaded
onto a device. For example, using the Play Core
Library, dynamic APKs
may be installed on demand after the base APK is installed on the device to
provide additional functionality to the user. Consider a chat app that downloads
and installs the ability to capture and send photos only when the user requests
to use that functionality. Because dynamic features may not be available at
install 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 the
base APK are available at install time. Google Play generates dynamic feature
APKs for your app from your project’s dynamic feature modules.

Consider an app with three dynamic feature modules and support for multiple
device configurations. Figure 1 below illustrates what the dependency tree for
the app’s various APKs may look like. Note that the base APK forms the head of
the tree, and all other APKs depend on the base APK. (If you're curious about
how the modules for these APKs are represented in an Android App Bundle,
see The Android App Bundle format.)

Figure 1. Dependency tree for an app served using split APKs

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

Devices running Android 4.4 (API level 19) and lower

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

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

Multi-APKs do not have the ability to later download dynamic features modules
on demand. To include a dynamic module in this APK, you must either disable
On-demand or enable Fusing when
creating the dynamic feature module.

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

Modularize your app

Reorganizing your app’s functionality into these discrete components takes
careful consideration and time. However, modularization provides your project
with the following benefits:

Develop in parallel: By separating logical components of your app into
modules, different teams or individuals in your organization can take ownership
of each module and work on them with fewer merge conflicts or disruptions to
other teams. Additionally, if you have logic that’s used in various parts of
your app, you can use library modules to promote code reuse and
encapsulation.

Improve build times: Build systems, such as the Android Studio build
system using Gradle, are optimized for projects that are organized into
modules. For example, if you enable Gradle’s parallel project
execution
optimization on a workstation includes a multi-core processor, the build
system is able to build multiple modules in parallel and significantly
reduce build times. The more modular your project is, the more significant
the build performance improvement becomes.

Customize feature delivery: Modularizing your app’s features as dynamic
feature modules is a requirement to take advantage of Dynamic Delivery’s custom
delivery options, such as on demand, conditional, and
instant delivery. Creating on demand dynamic features requires more effort and
possible refactoring of your app. So, consider carefully which of your app’s
features would benefit the most from being modularized into dynamic features
and benefiting from custom delivery options.

Use dynamic feature modules for custom delivery

A unique benefit of Dynamic Delivery is the ability to customize how and when
different features of your app are downloaded onto devices running Android 5.0
(API level 21) or higher. For example, to reduce the initial download size of
your app, you can configure certain features to be either downloaded as needed
on demand or only by devices that support certain capabilities, such as the
ability to take pictures or support augmented reality features.

Although you get highly optimized downloads by default when you upload your app
as an app bundle, the more advanced and customizable feature delivery options
require additional configuration and modularization of your app’s features using
dynamic feature modules. That is, dynamic feature modules provide the building
blocks for creating modular features that you can configure to each be
downloaded as needed.

Consider an app that allows your users to buy and sell goods in an online
marketplace. You can reasonably modularize each of the following functionalities
of 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 feature
modules support, and how they might be used to optimize the initial download
size of the sample marketplace app.

Delivery option

Behavior

Sample use-case

Getting started

At-install delivery

Dynamic feature modules that don’t configure any of the delivery options
described above are downloaded at app install, by default. This is an
important behavior because it means that you can adopt advanced delivery
options gradually. For example, you can benefit from modularizing your
app’s features and enable on demand delivery only after you’ve fully
implemented on demand downloads using the Play Core library.

In addition, your app can request to uninstall features at a later time.
So, if you require certain features at app install, but not after that,
you can reduce install size by requesting to remove the feature from the
device.

If the app has certain training activities, such as an interactive guide
on how to buy and sell items in the marketplace, you can include that
feature at app install, by default.

However, to reduce the installed size of the app, the app can request to
delete the feature after the user has completed the training.

If only 20% of those who use the marketplace app post items for sale, a
good strategy to reduce the initial download size for the majority of users
is to make the functionality for taking pictures, including an item
description, and placing an item for sale available as an on demand
download. That is, you can configure the dynamic feature module for the
selling functionality of the app to be downloaded only when a user shows
interest in placing items for sale onto the marketplace.

Additionally, if the user no longer sells items after a certain period of time,
the app can reduce its installed sized by requesting to uninstall the feature.

Allows you to specify certain user device requirements, such as hardware
features, locale, and minimum API level to determine whether a modularized
feature is downloaded at app install.

If the marketplace app has global reach, you might need to support
payment methods that are popular in only certain regions or locals. In
order to reduce the initial app download size, you can create separate
dynamic feature modules for processing certain types of payment methods and
have them installed conditionally on a user’s device based on their
registered locale.

Google Play Instant
allows users to interact with your app without needing to install APK(s)
on their device. Instead, they can experience your app through the "Try
Now" button on the Google Play Store or a URL that you create. This form of
delivering content makes it easier for you to increase engagement with your
app.

With instant delivery, you can utilize Google Play Instant to allow your
users to instantly experience certain features of your app without
installation.

Consider a game that include the first few levels of the game in a
lightweight dynamic feature module. You can instant-enable that module so
that users can instantly experience the game through a URL link or “Try
Now" button, without app installation.

Keep in mind, modularizing your app features using dynamic feature
modules is only the first step. To support Google Play Instant, the
download size of the base module of your app and a given instant-enabled
dynamic feature must satisfy strict size restrictions. To learn more,
read Enable
instant experiences by reducing app or game size.

Dynamic feature module manifest

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

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
Gradle settings file.

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 false.

<dist:module

This 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
create a instant-enabled dynamic feature
module.

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.

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.

<dist:fusing dist:include="true | false" />
</dist:module>

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.

Note: Dynamic feature modules should not specify activities in their manifest with
android:exported set to
true. That's because there's no guarantee that the device
has downloaded the dynamic feature module when another app tries to launch the
activity. Additionally, your app should confirm that a dynamic feature is
downloaded before trying to access its code and resources. To learn more, read
Manage installed modules.

Test Dynamic Delivery

The best way to test Dynamic Delivery is through the Google Play Store. That's
because a lot of the benefits of Dynamic Delivery rely on deferring optimized
APK generation, signing, and serving to the Play Store. So, whether you
include basic support for Dynamic Delivery by uploading an app bundle or
configure custom delivery options, you should use the following methods to test
your app with Dynamic Delivery"

Share your app with a URL.
This is the fastest way to upload your app bundle and share your app as a
Google Play Store link with trusted testers. Additionally, this is the fastest
way to test custom delivery options, such as downloading features on demand.

Considerations for dynamic features

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

Only devices running Android 5.0 (API level 21) and higher support
downloading and installing dynamic features on demand. To make your dynamic
feature available to earlier versions of Android, make sure to enable
Fusing when you create a dynamic feature module.

Make sure you
enable SplitCompat,
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 to
obtain user confirmation
before it can download the dynamic feature module to a device.

Dynamic feature modules should not specify activities in their manifest with
android:exported set to
true. That's because there's no guarantee that the device
has downloaded the dynamic feature module when another app tries to launch the
activity. Additionally, your app should confirm that a dynamic feature is
downloaded before trying to access its code and resources. To learn more, read
Manage installed modules.

Because dynamic delivery requires you to publish your app using an app bundle,
make sure that you're aware of app bundle
known issues.

Additional resources

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

Samples

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