Studying Now In Android App -Modularization

Julia Santos Moura
5 min readOct 13, 2022

--

Now in Android App” is a sample app developed by Google that aims to show the best practices in the Android world. This app shows articles from Now In Android Google’s series and allows you to follow specific topics and authors, among with other stuff.

My goal with this series of articles is to document my learning journey and maybe encourage someone to do the same. As I am getting in touch with new concepts and this will be written in real-time, maybe I will make some mistakes and misconceptions, feel free to give me advice and corrections!

The whole process starts by cloning the app in the link above:

When I first open the app it was not as what I expected:

I recommend the following article to understand the project structure:

So, “Now In Android App” uses the modularization strategy that aims to achieve low coupling and high cohesion. This means that you want to “put” similar things into the same “box” and that different “boxes” must have low dependencies upon each other:

Doing this has a lot of advantages as it increases scalability, reusability and helps teams to work in parallel because different teams are going to work in different “boxes” and have fewer conflicts.

But it also has some trade-offs. As you increase the quantities of “boxes” coordinating them together can become a complex task. You can also end up breaking your project into too many boxes, which may be difficult to manage and maintain. Or, the opposite: breaking it less than the ideal to achieve your goals. Keeping this balance is hard, but it’s possible.

These boxes in Android are modules, and this project has a lot of them:

According to the documentation:

“App: contains app level and scaffolding classes that bind the rest of the codebase […]

Features: feature-specific modules which are scoped to handle a single responsibility in the app.

Core: common library modules containing auxiliary code and specific dependencies that need to be shared between other modules in the app

Miscellaneous modules — such as sync, benchmark, and test modules”

Even though this clarifies how the project is structured, it is still a little foggy. For me, the best way to understand it is by following up on functionality through the app. So let's get started!

Let’s take a look at the author’s carousel. It is displayed in the ForYouScreen. Because of that, we can guess that part of its code is contained in the feature:foryou.

The app module handles the navigation logic through NiaNavHost which starts the navigation with the ForYouRoute. The route is defined in the feature. So here we can identify the first connection between two modules.

The ForYou feature module contains the ForYouScreen it uses, along with other stuff, NiaGradientBackground which creates that pink-orange background on the screen. This composable is defined at the core:designsystem module.

So, we can see that each module keeps only one responsibility: ForYou is encapsulating the functionality aspects of the ForYou flow while DesignSysten handles UI deeper implementation. This way, if another module needs to use the same background they can simply use NiaGradientBackground without creating a dependency on the ForYou module.

The ForYou module also contains a ViewModel which deals with the visualization logic of the screen. To display authors in the carousel the view model receives authorsRepository, an interface from the data module that is implemented by two repository classes that fetch the data.

Here the ForYou module delegates the responsibility of fetching the data to the data module. Doing it, if another module needs the same information it can get it without creating a dependency on the ForYou module.

One of the repositories that implement AuthorsRepository is the OfflineFirstAuthorsRepository which grabs this information from the database using AuthorDao, an interface defined in another core module: database.

So here, we identify that a module from the core layer can have a dependency from a module at the same "level". It is done to keep each module with a single responsibility and the communication between them is done through an interface.

The ForYou feature has many other functionalities and interacts with many other modules. But, with this simple example, we can see how the hierarchy between modules occurs: core modules do not see feature modules. And feature modules do not see app modules.

That ensures that layers that change constantly, such as core modules because they depend a lot on libraries and frameworks, do not cause internal layers, as feature modules that encapsulate functionality logic mainly, to refactor frequently. It is also relevant that we realize that each module has its specific responsibility, in other words, it module has only one reason to change.

This is just the beginning of this journey and I intend to cover each module and how they are organized in the build.gradle in other articles. Hope you enjoyed it and that it helped you!

Bye!

--

--