Quick Summary:
This is your ultimate guide on how to use Android app modularization for breaking down your monolithic Android project into multiple manageable and independent modules to ensure improved efficiency, speed, and safety of your overall project.
Have you wondered why there is so much noise around Android app modularization? What does modularizing Android apps mean, and how can it prove beneficial?
Don’t worry; it need not be as overwhelming.
The traditional monolith Android app structure is when the entire app works as a single unit where all the business logic is stored in a single place, and any changes made on any part of the app impact the entire app. Your entire app will need to be deployed again to reflect even the minutest changes made to the code.
Android app modularization breaks down this giant, monolithic structure and organizes the codebase into loosely coupled and self-contained modules. The modules are responsible for their specific functionalities, work independently and have a clearly defined purpose. Breaking down your complex Android project into modules can significantly reduce your project’s overall complexity, allowing dedicated teams to develop, design and maintain smaller modules efficiently.
Understanding the Monolithic Issue – eBay case study
Journey of Migration from Monolith to Modularize Android App
Before we get into greater detail about how to modularize Android apps, let’s look at an interesting case study.
Not long back (2021), eBay – one of the most famous multinational e-commerce platforms, shifted its monolithic Android app to feature-based modules.
eBay’s Android app was more than a decade old, containing many features and activity classes in horizontally layered monolithic modules –
- App Module – stored the presentation layer (UI) – responsible for all features related to UI classes
- Core/Infrastructure Module – stored all the supporting code such as cache, networking, logging
- Domain Module – stored the data layer – hosted all the app features and shared UI classes.
eBay Monolithic Android App Pain Points
eBay started facing issues with such a structure as their modules kept expanding in complexity and size.
- Tightly Packed Classes – Despite having an adequately structured package structure, standard classes would creep through the package boundaries, leading to the rigid and tight coupling of courses in any module.
- Increased Build Times – Since their monolithic modules kept growing, it delayed their build times for CI/CD tasks. The entire app had to be tested to identify the affected features by minor code changes.
- Increased App Size – Since the eBay team had to update the app with new features constantly, it inevitably increased the app download size. However, they could still manage this problem using Android app bundles.
eBay’s Incremental Approach to Android App Modularization
After carefully studying all ways to modularize the Android app, eBay’s team came up with a practical Android app modularization roadmap. They started by developing features in the new feature module to limit the size of their existing monolith feature module. They kept all their shared classes in their monolith modules since their analysis indicated that converting the entire shared codebase into smaller modules could take months. So, they took an incremental approach.
Their overall android app modularization process was broken down into three logical steps –
Process | Description |
Untangle | Break the significant dependencies of packages in a monolith. Refer to the standard classes that refer to each other across packages. |
Move | Move classes to a new module and packages. |
Modernize | Stay up-to-date with the latest Android developments, like using Kotlin, support modules, and components. |
With many other challenges and developments along the way, eBay successfully migrated to a more modular Android app enabling them to deploy on-demand features and scale their app as per changing requirements. To read about their migration in greater detail, you can check this official blog by Sangeetha on THENEWSTACK.
What is Android App Modularization? Challenges and Benefits
Since we already understand the concept of Android app modularization and even saw a case study that proves the benefits of Android app modularization, let’s understand this concept a little better and why it is worth your consideration.
Android app modularization can also be referred to as multi-module projects. Instead of dumping all your Android app components, functions, and other assets into a single or couple of monolithic modules, you organize your app’s codebase in loosely coupled, self-contained, independent modules. You build all the blocks independently and combine them to create your Android app.
Bottleneck and Challenges related to Android Modularization
Before moving forward with the benefits of modularizing Android apps, we should first take a look at some various challenges that you need to be aware of
Android App Challenges | Difficulty | Possible Workaround by Modularizing Android Apps |
Gradle | You must manually manage the Gradle dependencies and Android min to max versions. | It’s best to create a base Gradle file and use it around your modules. |
Circular Dependencies | Circular dependency is when two or more modules are directly or indirectly dependent on each other. This can be problematic as it can make the code difficult to test, maintain and read. | You can move standard code between two or more libraries and this common code into a new shared library. |
Navigation | Establishing proper navigation between the isolated app components can be challenging. | ⭐ Create an interface across feature modules and keep its implementation on the app module. ⭐ Load class using a qualified name |
Styles | One issue with monolith Android apps can be when you intend to change the style of a particular page but accidentally change the style of other pages, and the build time increases significantly. | You can divide the Gradle modules into independent UI libraries or modules, which helps clear the separation of concerns and also improve build time & performance. |
DI | General monolith Android apps have app modules on the top that knows all about the feature modules. This can lead to a messy dependency graph which can get complicated as the project grows. | With Android modularization, we can take the features module outside the core application where they can still be reached by the core application and other features but also be removed/replaced easily. |
Also Read : How Much Does it Cost to Develop an Android App?
What are the advantages of Android App Modularization?
The core focus or purpose of Android app modularization centers around improving codebase maintainability and quality of your codebase. However, it also provides many other benefits that might pique your interest or serve you well –
Optimal Code Reusability
For businesses that work on a multitude of projects simultaneously, modularizing Android apps can save them so much time and effort, subsequently even money. Defining independent modules with a specific purpose helps you to use the same module across different projects, eliminating the need to write that function from scratch every time. Moreover, you could publish some of the app modules as the library on platforms like GitHub and gain valuable input from the community.
Better Visibility Control
Dividing your project into smaller, independent modules lets you control what aspects or contents you want to expose to other parts of the codebase. Everything except the public interface can be marked as private or internal if you don’t want it to be used outside your module.
Play Feature Delivery
Play Feature Delivery is an exceptional Android feature that leverages the Android app bundles. Android app bundles generate optimized APKs, enabling users to download the only assets they need to run your app. Play Feature Delivery is a step up where certain Android app features can be delivered or downloaded on-demand.
Room for Experimenting
One of the biggest perks of having multiple modules to power your Android app is that each module functions separately without affecting/harming the other modules. This can be exploited for creating experimental app modules and testing any new library before using it on your real app modules.
Assigning Ownership and Accountability
When working on a giant monolith Android app, one of the most significant issues is finding problematic areas in the codebase and holding a particular talent or team responsible for that specific aspect. Since modularization in Android lets you break down the app into smaller modules, you can assign ownership and accountability for each module. This team or person will be responsible for code maintenance, bug fixes, testing, and reviewing changes.
More room for Scalability
One of the biggest benefits of using Android modularization architecture comes from the room for scalability it provides. The code in a monolithic Android app is tightly coupled, which means the resources are restrained to a specific interface or front end. All resources are purpose-driven, and any deviation or variation from it will need its resources and integrations. This can impose limitations on the extensibility and scalability of your project.
Loose coupling with Android app modularization is fundamentally the opposite of this concept. The components are loosely coupled and hence detached from each other. Any resource could have more than one frontend or application, and any application or frontend can utilize more than one resource. There is no destructive relationship that constrains the use case of any resources. This helps make your Android app future ready and easy to scale.
Efficient Testability
Code testability is an important aspect of any project. It determines how easy it is to test your app for various use cases and situations. For efficient code testing, the components should be tested in isolation. Since you’re essentially breaking down your Android app into smaller standalone modules, trying them in isolation becomes more accessible and faster.
Enable Encapsulation
It is easier to encapsulate your code with Android modularization. Each module works independently and only knows the information it needs to communicate with each other. This improves the overall code readability and ease of maintenance.
Reduced Build Time
This is one of the biggest benefits and the top reason Android app modularization is worth considering. As we already discussed, changing a basic color scheme in your traditional monolith app for it to run and show changes would need to rebuild the whole project. Whereas with android app modernization with fixed responsibilities and purposes assigned for individual modules, any changes made in that module would only affect the affected feature and the app module. Hence, we will only need to rebuild that specific aspect of the app, reducing build time drastically.
Parallel Development
You can separate logical components of your app into different modules, putting other teams in charge of these modules and later merging all the pieces. This allows development to progress parallelly instead of sequentially and also benefits the overall system since each development happens individually, so if something is to stop working suddenly, other aspects of the app can continue in their development endeavors unaffected.
Looking for Android App Developers?
Hire Professional Android App Developers from Aglowid to develop highly scalable mobile app
Android App Modularization Types – Understanding the different modules
Now that we understand Android modularization in depth, the next question is what are different Android common patterns, and which Android modularization pattern best suits my project? Since Gradle files provide room for flexibility, there are many ways you can organize your codebase with the modularization approach.
Types of Android Apps Modules
Let’s start by distinguishing and understanding different types of Android modularization. Other types of app modules will work differently for different projects.
Hence, you need a clearer insight into your project requirements to choose the right Android app modularization strategy.
Type of Android Modules | Description | Role |
Data Modules | Data modules contain repositories, model classes, and data sources. | Encapsulating all data and business logic of certain domains. |
App Modules | Container for your Android app’s source code, app-level settings, and resource files. | Providing a container for the Android app’s source code. |
Feature Modules | A feature is part of the overall functionality that responds to related screens, such as sign-up. | Encapsulating a distinctive feature of your Android app functionality. |
Common Modules | Also known as core modules that contain frequently used codes | For reducing redundancy. Some prime examples are the UI module, Analytics Module, Utility Module, and Network Module. |
Dynamic Support Modules | Support for Play Feature Delivery | Allows developers to separate some features and resources from the base module so you can add them to the app bundle |
Android App Modularization Testing Metrics
Ever wondered how to gauge the performance of your Android app modularization efforts? It is essential to understand the desired results before discussing how to modularize Android apps to test the common Android pattern’s efficiency in modularizing your Android app. Here are the three factors –
- Cohesion
- Coupling
- Granularity
Cohesion
Cohesion refers to the extent to which all the elements inside a module depend on each other. All the routines in a class and code in the routine should work towards a central purpose and act as a system. However, they should also have clearly defined structure and responsibilities while staying within the boundaries of specific domain knowledge. Such an ideal situation is known as high cohesion, which acts as a metric for defining an efficient Android app modularization process.
Coupling
Coupling refers to the extent of direct knowledge one element has of another. If they are tightly coupled, it means that changes made in element A will directly or significantly impact element B. This is why it is preferable to aim for low coupling with Android modularizing, where each element/module works as independently as possible.
Granularity
Though the formula above may look like an arithmetic equation that depends on data, it is more of a reference to understanding the granularity concept. Granularity measures the extent to which an app can be broken into different modules. For apps with heavy computational requirements, granularity can offload the overall load efficiently.
Achieving granularity in the right amount can be tricky. Here are the common pitfalls you might encounter when trying to achieve granularity –
Too Fine-Grained
When you create multiple modules, each module exerts a certain overhead on your boilerplate code and builds complexity. Complex configurations can harm consistency throughout your Android app modularization architecture, and too many boilerplate results in a highly complicated codebase which can get challenging to maintain. If your overhead expense limits your app’s scalability improvements, it’s better to consolidate some modules.
Too Coarse-Grained
Another instance is when your modules grow so large that you end up with YAM – yet another monolith. This beats breaking down a singular monolithic structure and modularizing the Android app. Hence, you must be careful of keeping your module sizes optimal.
Too Complex
Modularizing your Android app is great for specific use cases. However, it isn’t always the best possible solution. If the project is unlikely to grow or scale after a particular limit, you won’t gain any of the scalability or reduced build time modularized Android app has to offer. Hence, modularizing Android apps in such cases can lead to complex architectures and a waste of resources.
Also Read : How to Optimize Android App Performance in 2024?
Ways of Modularizing Android Apps – Common Android Patterns
Now that we understand the concept of Android app modularization and the perks of modularizing your Android app let’s look at the three most popular Android app modularization methods and appreciate their perks and limitations.
Android Modularization Patterns – By Feature
Let’s assume we are creating a simple movie database app with three screens – Movies, Directors, and Reviews. All these screens can be encapsulated in a module and defined as feature modules. Each feature module will have distinct responsibilities, developed in isolation, and work as a system.
However, what is the movie screen also wanting to show the director and review data? This could be achieved in two ways –
- The movie module could implement director and review functionalities already present in the other modules. This makes the codebase redundant, which is an ideal case when modularizing Android apps.
- Alternatively, we could establish that all three feature modules depend on each other, leading to a tight coupling that will prevent the features from being developed in isolation.
So modularizing an Android app by feature is not the most sought-after approach if you are looking to modularize a complex Android app that you want to scale. It could still work for smaller projects.
Android Functional Modularization Test
Functional Modularization Test | Movies | Directors | Reviews |
Loosely Coupled | ❌If the movies module requires to display director info or review info, it would need to request the other two modules or implement them, which goes against the loosely coupled principle. | ||
Granularity | ❌The system will be divided into different functions as new functions are introduced, which could work well for a medium-scale app; however, if it extends beyond a point, the app architecture could get too complex. | ||
Highly Cohesive | ✅the three modules are well structured, and their responsibilities are clearly defined, so they act as a system. |
Android Modularize Pattern – By Layers
Alternatively, we can also modularize the Android app via layers. Each layer will be responsible for a particular functionality. Android guidelines suggest the following layers – UI, Domain, and Data. Let’s break down the three layers –
- UI – the UI layers will be responsible for all the view models, composable or views.
- Domain – domain will handle the use cases and the business logic
- Data – The data layer is where all the repositories and data sources will be present
Separating these layers may work well for smaller projects but won’t work for larger ones. Let’s see how modularizing by layers does as per our previously discussed testing metrics.
Android Layer Modularization Test
Layer Modularization Test | UI | Domain | Data |
Loosely Coupled | ✅Changes made in UI will be limited to UI Module. | ✅Changes made in the domain could result in recompilation of the UI layer. | ❌ Altering the API or Data modules can lead to the recompilation of all the modules. |
Granularity | N/A | N/A | ❌Putting all the data inside a single module is not ideal for scalable projects as it makes the project too-coarse. |
Highly Cohesive | ❌ | ❌ | ❌ |
Android Modularization Pattern – Modularizing by Layer and Feature
As we can see, modularizing by layer and function, have merits and limitations. So, what do we do in such a situation? Why not use both? Yes, you read that right. We can combine the benefits of layer and feature modularization patterns and also overcome their limitations.
As you can see, this approach breaks down your Android monolith into multiple building blocks. All the UI blocks – ui:movies, ui:authors, and ui:reviews are part of the UI layer, dependent on domain and data modules. The domain modules will depend on data modules, and the data modules in the data layer won’t have access to the other two layers.
Android Layer and Function Modularization Test
Layer and Function Modularization Test | UI | Domain | Data |
Loosely Coupled | ✅All UI blocks work as independent modules and aren’t aware of other UI modules in the UI layer. Similarly, the UI layer, Domain Layer and Data Layer work separately with their respective function-based modules. | ||
Granularity | ✅Since we divide each and every function as a component and put them in the right layer, the granularity of app modularization works efficiently, leaving us with a lot of reusablae code that can also be shared as a library for other projects. | ||
Highly Cohesive | ✅Each module is highly independent and specialized. |
Wrapping Up!
This is your ultimate guide to Android app modularization. Now that you fully understand the benefits and limitations of modularizing your Android app, important types and testing metrics as well as ways of modularizing your Android app, you can take a strategic and incremental approach to breaking down your monolith to more manageable, performance oriented modularized app structure.
have a unique app Idea?
Hire Certified Developers To Build Robust Feature, Rich App And Websites.
Also Check: