This is a new series of articles called “Modern Android Development Tips, “or “MAD Skills” for short. Stay tuned for this series of articles dedicated to helping developers build better modern Android development experiences.

Today is the sixth article in this series: Configuring Play Feature Delivery for your app. If you would like to review past posts, please refer to the link below:

  • Overview of navigation components
  • Navigate to the dialog box
  • Use SafeArgs when navigating your application
  • Use deep links to navigate
  • Build your first App Bundle

In the “MAD Skills” series, the Android App Bundle is the default distribution format for Android apps.

On user devices, application file sizes using Android App Bundles are reduced by an average of 15% compared to generic APK files. By simply switching to the Android App Bundle, you can take advantage of it to save file sizes and improve distribution without changing any of your App’s code. In the second half of 2021, Google Play will require new apps and games to be released as Android App Bundles.

To learn more about how to build your first Android App Bundle, see the previous articles in this series.

Of course, you can also use Play Feature Delivery to further modularize and optimize the installation of your application.

Why modularize apps and Play Feature Delivery?

Modular applications create clear boundaries between different parts of the application, which brings all sorts of benefits.

Most of the time, you only need to rebuild a portion of your application, which can also help you reduce your application build time. Shorter build times and clear module boundaries may speed up project development.

At the same time, we can see from the Google Play Store:

Every 3 MB reduction in the download size of an app increases downloads by 1%

In this article, you can learn about the new features of Play Feature Delivery for Android App Bundles, which can help you further reduce the size of your application. I’ll also cover some apis that can be used to enable conditional or on-demand distribution of functionality, as well as various configuration options.

You can use Android Studio to experience the “New Module” process, and in this article we describe the logic behind the process and how you can change the configuration afterwards.

Building basic modules

When you start modularizing an application with feature modules, your base modules are install-time modules, and you already benefit from things like faster builds and faster engineering development.

The basic configuration of the module during installation is as follows:

/* Copyright 2020 Google LLC.spdx-license-Identifier: Apache-2.0 */<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="com.google.android.samples.playcore.picture">

    <uses-feature android:name="android.hardware.camera" android:required="true" />

    <dist:module dist:title="@string/module_feature_picture">
        <dist:fusing dist:include="true" />
        <dist:delivery>
            <dist:install-time />
        </dist:delivery>
    </dist:module>
</manifest>
Copy the code

The most important part is the Distribution Namespace, XMLNS: dist = “http://schemas.android.com/apk/distribution” and distributed configuration property is set to install – time.

Modules configured like this are installed by default when first installed.

Modules are merged into base modules at each installation, which makes them unremovable. If you want to be able to remove the install-time module later, you need to set its Removable property to true.

Some modules, such as tutorials and registration processes, take up a lot of storage and are only useful during the initial installation of the application, but are no longer needed once completed. For these modules, module offloading can be very useful.

We also provide a PlayCore API to install and uninstall certain modules on demand, which I’ll cover later in this article.

Tips for devices prior to Android 5.0

The installation mechanism of function modules should run on Android 5.0 and later models. For older versions of Android, feature modules can be placed in the base APK. To enable this function, you need to set the include attribute of fusing to true in the Module tag.

< dist: fusing dist: include = "true" >Copy the code

Set conditional distribution

Conditional distribution is another way to request functional modules in addition to install-time distribution. Installation conditions include device API version, user country, and device features.

This is a complete AndroidManifest configuration file.

/* Copyright 2020 Google LLC.spdx-license-Identifier: Apache-2.0 */<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="com.google.android.samples.playcore.picture">

    <uses-feature android:name="android.hardware.camera" android:required="true" />

    <dist:module dist:title="@string/module_feature_picture" >
        <dist:fusing dist:include="true" />
        <dist:delivery>
            <dist:install-time>
                <dist:conditions>
                    <dist:min-api dist:value="21"/>
                    <dist:max-api dist:value="29"/>
                    <dist:device-feature dist:name="android.hardware.camera"/>
                    <dist:user-countries dist:exclude="false">
                        <dist:country dist:code="DE"/>
                        <dist:country dist:code="GB"/>
                    </dist:user-countries>
                </dist:conditions>
            </dist:install-time>
            <dist:removable value="true" />
        </dist:delivery>
    </dist:module>
</manifest>
Copy the code

Not all of these conditions need to be set, and it is unlikely that you will need to use them all in a single module. Let’s explain them step by step.

To set distribution by conditions, we need to add the dist:conditions tag.

Then, by using min-API and max-API, you can declare the lowest and highest supported VERSIONS of the API.

These are useful if you need to specify API versions for a particular module.

In addition, every uses-feature element in the AndroidManifest file can be used as an installation condition. By using the device-feature attribute, you can ensure that feature modules are only distributed to devices with the relevant configuration.

By default, each user can download all of the application’s functional modules from the region where the application is published. You can select certain functional modules to be available only in certain countries. This can be a great way to implement localized applications. To do this, you need to add the user-countries tag and set a two-letter country code.

When you want to make a feature unavailable in certain countries, be sure to set dist:exclude=”false”. If you want a feature to be available only in one country, set this value to true.

Modules without code

Sometimes you just want to distribute a large resource file that looks like the TensorFlow model, and you don’t have any code in this feature module. Make sure that hasCode is set to false in the module’s AndroidManifest file.

<application android:hasCode="false" />
Copy the code

This setting tells the compiler not to generate the dex file.

If there is no code in the module and you forget to set hasCode to false, a runtime exception will result.

Distribute configuration on demand

If you want to fully control the installation time of your application, you can use on-demand Installation. This means that you can call the API to install modules after the application has been downloaded and installed on the user’s device.

Using an on-demand installation saves initial download time and size.

In the AndroidManifest file, you need to set the distribution option to on-demand. You can then use the PlayCore API to download, install, and uninstall modules in the flow of your application.

For more information about on-demand distribution in Play Feature Delivery, please refer to:

  • Example project for PlayCoreKtx on Github
  • Video: Configure Play Feature Delivery – MAD Skills for your application