JetPack Navigation For MultiModule Android Apps with DI
Hello everyone ✋🏻
I have long wanted to publish different posts and I finally summoned up the courage to start this one. I hope this post will be helpful to you and any questions or suggestions or improvements that you see please do not hesitate to comment on this post.
My story about Jetpack Navigation and Multi Module:
Two years ago I was assigned to redo a pretty big app in Java (almost 1M lines of code) in Kotlin and with a more modern architecture, tools and with a multi modular approach.
So my team started the challenge.
I wanted to use jetpack navigation because it seems to me a library that is quite simple to use and understand and covers most of the use cases of an app and also something that made me like a lot was the graphical editor that just by a fast look at it you could get an idea of how an app works, I think it’s wonderful.
The first solution I found was to use deep links, but I didn’t like that approach because it broke the mental flow of how normal navigation works, and I don’t think it would be that easy to maintain.
The next solution I saw was thanks to this post from David Vávra :
This solution was quite valid, and I used it for a long time because it seemed to me the best solution for navigation in apps with division by feature in multi modular approach, but this method had a peculiarity that is that all the navigation graph xml was in red, because the navigation module didn’t know about the feature modules and that’s why it was in red.
And a few months ago I thought about a solution with Dagger that could be better.
I thought to discuss it with a friend who is also very passionate about similar topics and he(Gabor Varadi) told me that he had written a post of a theoretical solution that he believed could work very well and seeing written something similar to what I was thinking I finally decided to try it out.
Gabor Varadi:
And here is my solution:
Simple Architecture for the example app
App can see every module.
Feature List Module can see Domain Module.
Feature Detail Module can see Domain Module.
Domain doesn’t know anyone. (This is just done to test the navigation of this post, I recommend breaking Domain in more modules, like Data Module for Networking and Data Class for Database, and depending on your case also use a Core Module…)
App Module:
The Nav Graph
Feature List Module:
List Navigation Interface
An interface showing all the possible navigations from Feature List Module we want to use from other modules (feature list module only knows about Domain Module)
Domain Module:
Data class for using navigation
We need to encapsulate the Args that we send from one module to another with safe args inside our own data classes, so we can access to it’s values
(Forever alone 😔 Domain doesn’t know about any other module)
Detail Module:
Detail Navigation Arguments Interface
An interface to show to other modules all the Safe Navigation Arguments from the jetpack navigation plugin to other modules. (feature detail only knows about Domain Module)
Back to app module:
Navigation Implementation:
We implement the navigation interface of the Feature List Module.
Args Implementation
We implement the args interface of the Feature List Module.
This is how we set up the dagger navigation module with hilt:
Nothing to comment here, just a dagger module for our navigation args and navigation interface.
Back to Feature List Module:
List Fragment
Here we use the Navigation Action to Navigate from Feature List Module to Detail Module passing a model as an argument.
Back to Detail Module:
Detail Fragment
Here we take the arguments inside the Detail Module from the Feature List Module
Conclusions:
Discussing with Gabor I agreed that the best would be that each feature module to have its own graph and that the app module would navigate from the nested feature list graph to the nested feature detail graph so each module had its own graph, but it gave me many problems with the global actions and passing and getting arguments from safeargs plugin using this approach.
If someone knows an example of navigation with arguments from one graph to another graph and using the navigation safe args plugin I would be grateful if you could show me an example so I would extend this post.
Here I share my github with the example project:
https://github.com/simtop/BillionBeers/tree/feature/multimodule_hilt
And also as I said this is my first post and I would be grateful to any criticism you have or if you see any helpful improvement in the project I would be really happy to hear your thoughts 😄.
Thank you for reading and Happy Weekend.