Instant & Dynamic Features
Everything so far assumes a user installs the whole app up front. Play Feature Delivery offers two more specialized options built on the same App Bundle format from earlier lessons. Both are genuinely advanced and fairly niche compared to everything else in this course — most apps, including RecipeBox as built throughout this tutorial, never need either one. They're covered here for awareness of what exists once an app's needs grow large enough to justify the extra complexity.
Google Play Instant: Try Before You Install
A Play Instant app (or "instant experience") lets a user run a lightweight version of an app directly from a Play Store listing, a web link, or a "Try Now" button — without installing anything first. If RecipeBox offered this, tapping a shared recipe link could open a live, limited RecipeBox experience showing just that one recipe, with a normal "Install" prompt available if the user wants the full app afterward.
User taps link
No RecipeBox installed
Instant experience streams
Small, capped-size module runs immediately
Optional install
User can install the full app to keep using it
Dynamic Feature Modules: On-Demand Delivery
A Dynamic Feature Module is a separate Gradle module bundled into the same App Bundle, but not downloaded at install time — it's fetched later, only if and when a user actually needs it. Imagine RecipeBox adding an optional "Meal Planner" module (drag recipes onto a weekly calendar, generate a shopping list) that most users would never touch: shipping it as a dynamic feature keeps the base install small for everyone, and only meal-planning users ever download that extra code.
// settings.gradle
include ":app", ":mealplanner"
// mealplanner/build.gradle (Groovy DSL)
plugins {
id 'com.android.dynamic-feature'
}
android {
namespace "com.example.recipebox.mealplanner"
compileSdk 34
}
dependencies {
implementation project(":app")
}
// app/build.gradle (Groovy DSL) — base module declares the feature
android {
dynamicFeatures = [":mealplanner"]
}
- The com.android.dynamic-feature plugin marks :mealplanner as a module Play can deliver separately, rather than a normal library module always bundled in.
- dynamicFeatures on the :app module lists every such feature so the bundling process knows they exist.
- The feature module depends on :app (for shared classes like Recipe), not the other way around — the base app must work fine with the feature never installed at all.
SplitInstallManager Basics
At runtime, requesting a dynamic feature's download goes through SplitInstallManager from the Play Core library, which reports progress and completion the same way the earlier Firebase Storage lesson's UploadTask listeners did.
// Inside an Activity, when the user taps "Open Meal Planner"
SplitInstallManager splitInstallManager = SplitInstallManagerFactory.create(this);
SplitInstallRequest request = SplitInstallRequest.newBuilder()
.addModule("mealplanner")
.build();
splitInstallManager.startInstall(request)
.addOnSuccessListener(sessionId -> {
Log.d("RecipeBox", "Meal Planner module installed");
openMealPlannerScreen();
})
.addOnFailureListener(e -> {
Log.e("RecipeBox", "Meal Planner module failed to install", e);
});
When (Not) to Reach for This
Use dynamic features when: a genuinely large, optional piece of functionality is used by a small minority of users, and the base app's install size matters enough to justify the added build complexity.
Skip them when: the app is small-to-medium sized already (RecipeBox, as built in this course, would not benefit), or when App Size Optimization techniques already keep the base install reasonably lean.