Splitting an Android application into two or more parts is not just a technical trick, but a strategic decision that can significantly improve the user experience experience, reduce the size of the installation package and optimize resource loading. In an era when the average size of applications exceeds Google Play exceeds 100 MB, and users are increasingly faced with limited space on their devices, proper separation of functionality becomes critical.

But how exactly to do this? There are several approaches - from using Dynamic Feature Modules (dynamic function modules) to the classic division into basic and additional APK. Each method has its pros, cons and specific applications. In this article we will analyze all current ways to split an Android application into two parts in 2026including step-by-step guide, code examples and optimization recommendations.

It is important to understand that splitting an application is not only a technical challenge, but also an architectural one. Getting it wrong can result in longer load times, dependency conflicts, or even crash the app on some devices. Therefore, before starting work, you should carefully analyze the structure of your project and determine which parts can be divided into separate modules.

Why divide the application into parts: key advantages

Before moving on to the technical implementation, let's take a look at why it is even worth splitting the application into several parts. Here are the main reasons that motivate developers to take such a step:

  • ๐Ÿ“‰ Reducing the size of the base APK: Users will be able to download and install only the required minimum, and additional functions will be downloaded on demand.
  • ๐Ÿ”„ Flexible updating: You can update only individual modules without forcing users to download the entire package again.
  • ๐ŸŒ Localization and regional features: Moving language packs or region-specific functions into separate modules.
  • ๐Ÿ› ๏ธ A/B testing: It is easier to test new features on part of the audience without affecting the main application.
  • ๐Ÿ’ฐ Saving traffic: Especially relevant for users with limited tariffs or slow Internet.

However, this approach also has a downside. For example, increasing the complexity of support: you will have to monitor compatibility between modules, manage their versions and ensure correct operation on different devices. It is also worth considering that not all functions can be placed in separate parts - some system components (for example, ContentProvider or BroadcastReceiver) must be available immediately after installation.

โš ๏ธ Attention: If your application uses Google Play Billing Library For in-app purchases, make sure that all dynamic modules are properly integrated with the payment system. Otherwise, users may lose access to purchased features after the update.

Method 1: Dynamic Feature Modules (DFM) - a modern approach

Dynamic Feature Modules is the recommended Google way of dividing an application into parts, which works in tandem with Android App Bundle (AAB). The basic idea is that the base application contains only critical components, and the remaining functions are loaded on demand or upon first launch.

To start using DFM, you will need:

  1. Update build.gradle to the latest version Android Gradle Plugin (not lower 7.0.0).
  2. Create a new module of type dynamic-feature in Android Studio.
  3. Configure dependencies between the main application and the dynamic module.
  4. Implement the logic for loading and installing the module via SplitInstallManager.

Structure example build.gradle for the dynamic module:

plugins {

id 'com.android.dynamic-feature'

id 'kotlin-android'

}

android {

compileSdk 34

defaultConfig {

minSdk 21

}

}

dependencies {

implementation project(':app') // Dependency on the main module

implementation 'androidx.core:core-ktx:1.12.0'

}

To load the module in runtime, use the following code:

val splitInstallManager = SplitInstallManagerFactory.create(context)

val request = SplitInstallRequest.newBuilder()

.addModule("dynamic_feature_name")

.build()

splitInstallManager.startInstall(request)

.addOnSuccessListener { / Module installed / }

.addOnFailureListener { / Error handling / }

โš ๏ธ Attention: Dynamic modules require that the application be published in Google Play format. If you distribute the application through other channels (for example, Android App Bundle (AAB). If you distribute the application through other channels (for example, APK on your site), this method will not work.
๐Ÿ“Š What method of splitting the application do you plan to use?
Dynamic Feature Modules
Split APKs
App Bundles with lazy loading
Not decided yet

Method 2: Split APKs - classic split

If your application is not published in Google Play or you need to support older versions of Android (below API 21), you can use the Split APKs. In this case, the application is divided into several APKfiles, which are installed as a single whole.

Main types of splits:

  • ๐Ÿ“ฆ Base APK - contains the main code and resources required for work.
  • ๐ŸŒ Configuration APKs - division by screen density, languages or architecture processor.
  • ๐Ÿ”ง Feature APKs โ€”additional functions that can be downloaded separately.

To configure Split APKs in build.gradle use the following block:

android {

splits {

// Separation by architecture

abi {

enable true

reset()

include 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'

universalApk false

}

// Separation by language

language {

enable true

include 'en', 'ru', 'es'

}

}

}

After assembly, you will receive several APKfiles that can be downloaded separately. For example:

  • app-base.apk โ€” the main package;
  • app-x86.apk โ€” for devices with architecture x86;
  • app-ru.apk โ€”language package for the Russian language.
Split type Advantages Disadvantages
Base + Config APKs Reduces the size of the installation package due to the removal of resources Difficult to maintain if there are many configurations
Feature APKs Flexible control of functions, can be downloaded on demand Requires manual processing installation
Universal APK Easy distribution (one file) Large size, not optimized for devices

One of the main disadvantages of this method is complexity of version management. If you are updating only one of the splits, you need to make sure that it is compatible with the others. Users may also encounter problems if one of APKfiles does not load or is damaged.

Check the minimum Android version (API 21+ is recommended)

Determine which resources can be moved to configuration splits

Configure dependencies between modules in build.gradle

Test the installation on different devices

Prepare an update system for splits-->

Method 3: App Bundles with lazy loading

Android App Bundle (AAB) is a publishing format that allows Google Play automatically generate and deliver optimized APK for each device. One of the key features AAB is the possibility of Lazy loading (on-demand delivery) of individual components.

Unlike Dynamic Feature Modules, where modules are loaded on demand at runtime, lazy loading via AAB allows:

  • ๐Ÿ“ฅ Load additional components when the application is first launched;
  • ๐Ÿ”„ Update only certain parts of the application;
  • ๐ŸŽฏ Targeted content delivery (for example, load game levels only when the user reaches them reaches).

To configure lazy loading in build.gradle a dynamic module, add the following:

android {

bundle {

language {

enableSplit = true

}

density {

enableSplit = true

}

abi {

enableSplit = true

}

}

dynamicFeatures = [':dynamic_feature_module']

}

To initialize loading of the module at the first start, use SplitInstallManager:

val splitInstallManager = SplitInstallManagerFactory.create(context)

val request = SplitInstallRequest.newBuilder()

.addModule("premium_features")

.build()

splitInstallManager.deferredInstall(listOf(request))

It is important to consider that lazy loading only works through Google Play. If the user installs the application from another source (for example, via APK), additional modules will not be loaded. It's also worth remembering that Google Play may cache modules, so changes are not always applied instantly.

๐Ÿ’ก

If your application uses Firebase Remote Configyou can combine it with lazy loading of modules. For example, enable the download of premium features only for users with an active subscription.

Problems and solutions when splitting an application

Splitting an application into parts is not always a smooth process. Here are the most common problems that developers face and how to solve them:

Problem Cause Solution
Module does not load No Internet connection or error in SplitInstallRequest Add error handling and retries
Conflict versions Incompatibility between the base APK and the module Use versionCode and check compatibility
Increasing startup time Additional checks for modules Cache module state and load asynchronously
Problems with ProGuard Incorrect obfuscation rules for dynamic modules Configure separate rules for each module

One of the most insidious problems is this context leak when working with SplitInstallManager. If you don't free resources correctly, it can lead to memory leaks and application crashes. Always use lifecycleScope for coroutines or LiveData to monitor loading status.

Another common mistake is tight binding to module names. If you hardcode the names of modules in the code, then when they are renamed, you will have to rebuild the entire application. Instead, store names in strings.xml or use constants.

โš ๏ธ Attention: If your application uses Native Libraries (SO files), make sure they are distributed correctly between modules. Some architectures (for example x86) may require additional configuration to work correctly.

Optimization and testing of a split application

Once you have split your application into parts, it is necessary to conduct thorough testing and optimization. Here are the key aspects to pay attention to:

  • ๐Ÿ” Testing on different devices: Make sure that all modules work correctly on different Android versions and architectures.
  • ๐Ÿ“Š Size monitoring: Make sure that the base one APK remains as small as possible (preferably less than 15 MB).
  • โšก Performance: Measure module loading time and optimize network requests.
  • ๐Ÿ”„ Updates: Ensure that users receive the latest versions of modules without forcing reinstallation.

To automate testing, you can use Firebase Test Lab, which allows you to test the application on hundreds of devices in the cloud. Pay special attention to scenarios with a poor Internet connection - users should not lose functionality if the module does not load.

It is also recommended to implement a system fallback in case the module cannot be loaded. For example, if premium features are not loaded, show the user a notification asking them to try again or switch to the main functionality.

To analyze the effectiveness of the division, use Google Play ConsoleThere you will find data on how many users have downloaded additional ones. modules, which of them are the most popular, and how this affects audience retention.

What to do if the module does not load on devices with Android 10 and below?

On devices with Android 10 (API 29) and below there may be problems loading dynamic modules due to restrictions SplitInstallManager. In this case, it is recommended:

1. Use SplitInstallManager.startInstall() with an explicit indication SplitInstallRequest.

2. Check support for dynamic features via SplitInstallManager.isInstallRequestUpdateTypeAvailable().

3. For critical functions, duplicate them in the base APK and check for availability. module.

Examples of successful application separation

Many popular applications already use partitioning to optimize performance. Here are some striking examples:

  • ๐ŸŽฎ PUBG Mobile: The main package weighs about 600 MB, but additional maps and modes are downloaded on demand.
  • ๐Ÿ“ท Instagram: Functions like Reels or Shopping can be loaded separately depending on the user's region.
  • ๐ŸŽต Spotify: Music tracks and podcasts are stored in separate modules, which reduces the size of the base application.
  • ๐Ÿ—บ๏ธ Google Maps: Maps of regions are loaded as needed, saving space on the device.

These apps demonstrate how smart separation can improve the user experience. For example, PUBG Mobile allows players to download only the maps they actually use, and Google Maps saves bandwidth by downloading detailed maps only for the current location.

If you're developing a game, chunking is especially important. You can put into separate modules:

  • ๐ŸŽฎ Levels and locations;
  • ๐ŸŽจ Textures and high-resolution 3D models;
  • ๐Ÿ”Š Sound effects and music;
  • ๐Ÿ“œ Storylines and dialogues.

This not only reduces the size of the installation package, but also allows you to update content without releasing a new version of the game.

๐Ÿ’ก

Dynamic modules are especially effective for games and multimedia applications, where content can be divided into logical blocks (levels, episodes, regions).

FAQ: Frequently asked questions about division Android applications

Is it possible to split an application if it is already published on Google Play?

Yes, but this will require careful preparation. You need to:

  1. Update the application version (versionCode).
  2. Move some of the functionality to dynamic modules.
  3. Test backward compatibility.
  4. Publish the update as Android App Bundle.

Users who update the application will receive the new structure automatically. Those who do not update will remain on the old version.

How to ensure compatibility between the base APK and dynamic modules?

Use version contracts:

  • Store the module version in AndroidManifest.xml;
  • Check compatibility when loading via SplitInstallManager;
  • Use versionCode to manage dependencies.

If a module requires a specific version of the base APK, indicate this in build.gradle:

android {

defaultConfig {

minSdk 21

// Minimum version of the base APK with which compatible module

splitInstall {

minSdkForInstall 23

}

}

}

Is it possible to share an application without using Google Play?

Yes, but with limitations. Options:

  • Split APKs: Manual distribution and installation of several APKfiles.
  • Downloading resources from the server: Storing part of the content on a remote server and downloading on demand.
  • Plugins: Usage systems like DroidPlugin (outdated) or custom solutions.

However, these methods require manual processing of dependencies and updates, which complicates support.

How to reduce the size of the base APK when splitting?

Some tips:

  • Use WebP instead of PNG/JPEG for images;
  • Use ProGuard/R8 to remove unused code;
  • Move heavy libraries (for example, TensorFlow Lite) into dynamic modules;
  • Use Android Size Analyzer to analyze the composition of the APK.

The goal is to keep within 10-15 MB for the basic package to increase installation conversion.

What are the limitations of Dynamic Feature Modules?

Main restrictions:

  • Work only through Google Play (not suitable for third-party stores);
  • Require Android 5.0 (API 21) or higher;
  • Not support Instant Apps;
  • May increase first launch time due to module checking.

If these limitations are critical, consider alternative methods like Split APKs or downloading content from the server.