How Android Handles the Installation of Feature Modules

Shashank kumar
5 min readJul 29, 2024

--

With the rollout of Android App Bundles, AAB, and Google have given a different way through which the distribution and installation of apps are managed using Feature Modules and Split APKs.
Feature Modules let the developer modularize their application, allowing the installation of certain application features upon request. It enables this modular approach through Split APKs, fragmenting the app into multiple small APKs targeted at different device configurations and user needs.

On installation, Google Play dynamically assembles and delivers the right Split APKs for every device, considering screen density, CPU architecture, and users’ preferred language. This not only optimizes the app's size using this approach, but it also makes the installation process more effective and flexible.

Let’s dive deeper into how the Android framework handles the Installation of these Split APKs.

The Package Manager handles the installation of both the base APK and split APKs. It verifies the APKs’ signatures, extracts their contents, and stores them in the appropriate directories.

It stores metadata about the installed APKs, including information about the base APK and its associated split APKs. This metadata is essential for identifying and managing the different components of the app.

The Package Manager ensures that all necessary split APKs are installed and available for the base APK to function correctly. It tracks dependencies between the base APK and its splits.

During installation, the PackageManager reads the manifest of each APK. It uses the “package” attribute to confirm the package name and the “split” attribute to distinguish between the base and split APKs. The base APK is typically identified by the absence of the “split” attribute in its manifest. It has a null or empty split name. Split APKs contain a “split” attribute in their manifest files, which specifies the split name. This differentiates them from the base APK.

Whenever an app install is triggered PackageManager is invoked and eventually PackageInstaller delivers the app for Installation.

PackageInstaller Offers the ability to install, upgrade, and remove applications on the device. This includes support for apps packaged either as a single “monolithic” APK, or apps packaged as multiple “split” APKs.

An app is delivered for installation through a PackageInstaller.Session, which any app can create. Once the session is created, the installer can stream one or more APKs into place until it decides to either commit or destroy the session.

A Session is where APKs and related files are prepared for installation.

PackageInstaller.Session is a static inner class used for managing an install session, providing methods for writing APKs, setting progress, committing the session, and more.

An app is delivered for installation through PackageInstaller.Session. Once the session is created, the installer can stream one or more APKs into place until it decides to either commit or destroy the session.

Sessions can install brand-new apps, upgrade existing apps, or add new splits into an existing app.

Apps packaged as multiple split APKs always consist of a single “base” APK (with a null split name) and zero or more “split” APKs (with unique split names). Any subset of these APKs can be installed together, as long as the following constraints are met:

  • All APKs must have the same package name, version code, and signing certificates.
  • All APKs must have unique split names.
  • All installations must contain a single base APK.

PackageInstaller.Session is an installation that is being actively staged. For an install to succeed, all existing and new packages must have identical package names, version codes, and signing certificates. A session may contain any number of split packages. If the application does not yet exist, this session must include a base package.

If an APK included in this session is already defined by the existing installation (for example, the same split name), the APK in this session will replace the existing APK.

A Session Param is set for every session, MODE_INHERIT_EXISTING Mode for an install session that should inherit any existing APKs for the target app, unless they have been explicitly overridden (based on split name) by the session. For example, this can be used to add one or more split APKs to an existing installation.

openWrite(String name, long offsetBytes, long lengthBytes) opens a stream to write an APK file to the session and calls write(@NonNull String name, long offsetBytes, long lengthBytes, @NonNull ParcelFileDescriptor fd which writes data to the session from a file descriptor.

Dynamic Feature modules are treated as distinct APKs or files. They are added to the session using methods such as openWrite() for writing data. Each feature module can be managed separately but within the context of the same installation session.

Methods like removeSplit() are used to handle these splits, ensuring that old or unnecessary splits are removed before new ones are added.

When multiple Dynamic Feature Modules need to be installed or updated simultaneously, a multi-package session can be used. A multi-package session is created without a specific package name by calling SessionPrams#setMultiPackage().

Once all data is added and verified, the session is finalized. This can be done by calling commit(IntentSender) to finalize and apply the changes. Alternatively, the session can be abandoned if something goes wrong.

Session Process Diagram

The Split APK Installation Process can be seen as follows -

  1. The system determines the current device configuration
  2. Based on the device configuration and the metadata stored by the Package Manager, the system identifies the required split APKs.
  3. The system verifies if the identified split APKs are already installed. If they are, the system proceeds to the next step. If not, the system initiates a download or installation process.
  4. Once the required split APKs are available, the app’s runtime environment loads the necessary classes and resources from them. This is typically handled by the SplitCompat library.
  5. The resource manager resolves resources based on the device configuration, giving priority to resources from split APKs that match the device’s characteristics.

For more information on feature modules —

--

--