Local development and testing with on-demand modules
Over the past few months I’ve been working on addressing some of the feedback I got from developers who were using dynamic feature modules in their apps. A common theme was the lack of good testing support and their speed of development being affected by having to upload an artifact to the Play Store to be able to try the module download and installation flows.
Last year, at Android Dev Summit, I gave a talk with some colleagues working on Play’s Dynamic Delivery, in which we teased a new feature in the Play Core library called the FakeSplitInstallManager
that makes it possible to perform some of the operations, such as installing on-demand modules, locally.
While the FakeSplitInstallManager
class has been available for a while now (since Play Core 1.6.4), it took a bit of time to get the developer experience right and land the final changes to bundletool
that were required to automate the process.
Today you can check out how it works in one of our new samples:
Previously, whenever we released samples that showcased the use of downloadable dynamic feature modules, we had to include instructions for developers to
1) change the package name of the sample app,
2) create an app entry on your Play Console account,
3) upload the bundle to internal app sharing or the internal testing track… Very cumbersome if you just want to experience using the API!
All of the above is not needed anymore if you just want to quickly play with the sample and see how it works locally.
This is thanks to a new --local-testing
flag added in bundletool version 0.13.0.
When applied to the bundletool build-apks
command, the flag instructs bundletool
to add a small piece of meta-data to the generated APK’s manifest. You can then use this in two simple steps:
- Install your app on a test device (or emulator) with
bundletool install-apks
. This triggers an additional push of all split APKs to a location on the device’s storage. - Run the app and create a
SplitInstallManager
using the usual factory methodSplitInstallManagerFactory.create(Context)
.
The returned instance now automatically detects the presence of the local testing meta-data and uses FakeSplitInstallManager
under the hood, installing requested modules from local files rather than by downloading from Play. You must use Play Core 1.6.5 or newer for this to happen automatically.
To make it even simpler, I’ve added a new Gradle task in the sample to streamline running the bundletool commands that I mentioned:
./gradlew installApkSplitsForTestDebug
Unfortunately this functionality is still not available from Android Studio GUI or from the Android plugin for Gradle directly. The task you see here is just a quick hack, equivalent to running the following commands on your project:
./gradlew bundleDebugbundletool build-apks --overwrite --local-testing --bundle path/to/bundle.aab --output path/to/apkset.apksbundletool install-apks --apks path/to/apkset.apks
If you want to know how I added these tasks, take a look at the build script source. UPDATE: Take a look at our newer PlayCoreKTX sample to see how it’s done using the new Android Gradle plugin APIs.
Please note: not all SplitInstallManager
functions are implemented in local testing mode or when calling FakeSplitInstallManager
directly (e.g. when writing tests).
You can:
- Request, monitor and cancel module/language installs.
- Handle install errors.
- Use SplitCompat to immediately access modules.
- Use Play Core KTX (Kotlin extensions).
What’s not supported due to technical limitations (i.e. we have no current plans to add this):
- Uninstalling modules.
- Requesting deferred installs/uninstalls.
- Starting a confirmation dialog for large modules.
- More than one installation session running.
For further reading, please refer to the updated documentation.
By the way, the sample that I linked in this article showcases another library that I’ve worked on together with Ben Weiss, which makes it easier to integrate on-demand modules in your app when using the Navigation architecture component.
The dynamic feature navigator is an extension on top of the base navigation library that lets you define navigation destinations (such as Fragments, Activities) that come from dynamic feature modules.
If the module is installable on-demand the library takes care of downloading and installing it using the Play Core API, and even provides a default progress UI. At the same time, it is as customizable as you need it to be. You can read more in the new documentation page.
The library is currently in alpha and we welcome your feedback.