I have an Android project which is architectured in a Modularized way. I have modularized the projects by dividing their source code between multiple Gradle modules, following the clean Architecture.
Here is the structure of the App.
The top module in this hierarchy, App
is the one that no other module depends upon, is the main module of your application. The lower level modules domain
and data
do not depend on the App
module, where the App
module includes the data
and domain
modules. I have added the below code in the build.gradle of the app
module
implementation project(':domain')
api project(':data')
Now, I'm having some issues with maintaining dependencies across each module. Since each of them is an individual android module, each of them having its own build.gradle
. The App
module can use classes in the data
and domain
modules. But, I have some general purpose classes, (Such as some annotations, Utilities, Broadcast classes, Dagger scopes etc) which I want to make use in all the modules. But these are the issues I'm facing
- Since these classes are contained in the main module
app
, I cannot access these in mydata
anddomain
, because those modules do not depend on the higher layerapp
- Any libraries I'm using in all the layers (eg: RxJava) needs to be included in the
build.gradle
of each module
As a solution for this I thought of adding one more android module, say common
which will be containing all my general purpose classes as well as the libraries which I use in all the modules.
All my other modules app
, domain
and data
will be having this module as a dependency.
implementation project(':common')
So, any global libraries and classes will be added to this module and each of the individual modules will have only module-specific classes.
Is that a good approach? Or is there any way to solve this issue efficiently?
We recently encountered this problem, as we transitioned to a multi-module project for reuse, build time optimisation (unchanged modules aren't recompiled), etc. Your core goal is to make your app
module as small as possible, as it will be recompiled every time.
We used a few general principles, which may help you:
- A common
base-ui
module contains the primarystrings.xml
,styles.xml
etc. - Other front-end modules (
profile
,dashboard
, etc) implement thisbase-ui
module. - Libraries that will be used in all user-facing modules are included in
base-ui
, as anapi
instead ofimplementation
. - Libraries that are only used in some modules are added as dependencies only in those modules.
- The project makes extensive use of data syncing etc too, so there are also
base-data
,dashboard-data
etc modules, following the same logic. - The
dashboard
feature module depends ondashboard-data
. - The
app
module depends only on feature modules,dashboard
,profile
, etc.
I strongly suggest sketching out your module dependency flow beforehand, we ended up with ~15 or so modules, all strictly organised. In your case, you mentioned it's already quite a large app, so I imagine app
needs feature modules pulled out of it, as does domain
. Remember, small modules = less code to be recompiled!
We encountered some issues with making sure the same version (buildType
, flavors
) of the app was used across all submodules. Essentially, all submodules have to have the same flavor
s and buildType
s defined as the app
module.
On the other side of the coin, multi module development does really make you think about dependencies, and enforces strict separation between features. You're likely to run into a few unexpected problems that you've never considered before. For example, something as simple as displaying the app's version suddenly complicates (disclaimer: my article).
This article also helped us decide on our approach. The article you linked also seems to be an excellent resource, I wish it had existed when we'd transitioned!
After comment discussion, here's an example diagram (with unfortunate untidiness, but enough to illustrate the concept. Note that distinguishing between api
and implementation
would be a good next step):
来源:https://stackoverflow.com/questions/54104312/how-to-share-dependencies-in-a-modularized-android-app