In this article, we will talk about the dynamic module that allows us to separate certain features and resources from the application’s base module and include them in the application package. Through dynamic delivery, users can then download and install features after they have installed the application’s basic APK.
To understand this in detail, we will consider the basic ringtone application in which users can play and set ringtones on their phones:
Having an “About” fab button in the first image that we found is rarely used by users. So instead of providing this feature with the base APK, we will create a separate dynamic feature module in the base code, where there will be code for Introduction only. For this, we will first add a “dynamic feature module”:
At the last step of this procedure, check both “Enable on-demand” and “Fusing”. Fusing for pre-Lollipop devices does not support the dynamic feature module, the “About” module will be installed and downloaded with the APK base:
Then we can see below that we have our own module added to the project. There is another build.gradle as well as a manifest file.
And don’t forget to establish a relationship with the base module:
1 | // In the base module's build.gradle file. android { ... // Specifies dynamic feature modules that have a dependency on // this base module. dynamicFeatures = [":dynamicFeature"] } |
1 | // In the dynamic feature module's build.gradle file: ... dependencies { ... // Declares a dependency on the base module, ':app'. implementation project(':app') } |
Now it’s time to see the download code and install the About module. We will handle this function in the onclick of the About: button.
1 | mFabButton!!.setOnClickListener { // Creates a request to install a module. var request: SplitInstallRequest = SplitInstallRequest .newBuilder() // You can download multiple on demand modules per // request by invoking the following method for each // module you want to install. .addModule("dynamicFeature") .build() // Skip loading if the module already is installed. Perform success action directly. if (manager.installedModules.contains("dynamicFeature")) { //updateProgressMessage("Already installed") onSuccessfulLoad("dynamicFeature", launch = true) } manager.startInstall(request) } |
And in the OnCreate () of MainActivity of the basic feature:
1 | // initialize SplitInstallManager. manager = SplitInstallManagerFactory.create(this) SplitCompat.install(this) |
We need to have a listener when requesting to install the About feature in the first code:
1 | ** Listener used to handle changes in state for install requests. */ private val listener = SplitInstallStateUpdatedListener { state -> val multiInstall = state.moduleNames().size > 1 state.moduleNames().forEach { name -> // Handle changes in state. when (state.status()) { SplitInstallSessionStatus.DOWNLOADING -> { // In order to see this, the application has to be uploaded to the Play Store. //displayLoadingState(state, "Downloading $name") Toast.makeText(this,"downloading",Toast.LENGTH_SHORT).show() } SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION -> { /* This may occur when attempting to download a sufficiently large module. In order to see this, the application has to be uploaded to the Play Store. Then features can be requested until the confirmation path is triggered. */ //startIntentSender(state.resolutionIntent()?.intentSender, null, 0, 0, 0) } SplitInstallSessionStatus.INSTALLED -> { Toast.makeText(this,"installed",Toast.LENGTH_SHORT).show() onSuccessfulLoad(name, launch = !multiInstall) } SplitInstallSessionStatus.INSTALLING -> Toast.makeText(this,"installing..",Toast.LENGTH_SHORT).show() SplitInstallSessionStatus.FAILED -> { //toastAndLog("Error: ${state.errorCode()} for module ${state.moduleNames()}") Toast.makeText(this,"failed",Toast.LENGTH_SHORT).show() } } } } |
But wait, we’ve missed an onSuccessfulLoad () method name, add this implementation:
1 | private fun onSuccessfulLoad(moduleName: String, launch: Boolean) { if (launch) { Toast.makeText(this,"Onsuccessfulload",Toast.LENGTH_SHORT).show() var intent1 = Intent(this, Class.forName("com.example.dynamicfeature.MainActivity")) startActivity(intent1) } } |
This will launch the MainActivity feature of the About us feature. The first time it may take a while to launch because the download is required but then it will act as an opportunity.
The significant benefit of this dynamic module is that it reduces the size of the application because we are providing additional features on demand.
And, the important point to note is that we will upload the application package (.aab) instead of .apk for this delivery.
Source: https://medium.com/mindorks/dynamic-feature-module-using-android-app-bundle-d5b163aaf91d