如何在模块化Android应用程序中共享依赖项 [英] How to share dependencies in a Modularized Android App
问题描述
我有一个以模块化方式进行架构的Android项目.我已经按照 clean Architecture 的方式在多个Gradle模块之间划分了源代码,从而对项目进行了模块化.
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.
此层次结构中的最高模块App
是其他模块所不依赖的模块,它是应用程序的主要模块.较低级别的模块domain
和data
不依赖于App
模块,其中App
模块包括data
和domain
模块.我在app
模块的build.gradle中添加了以下代码
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')
现在,我在维护每个模块之间的依赖性时遇到了一些问题.由于每个都是独立的android模块,因此每个都有自己的build.gradle
. App
模块可以使用data
和domain
模块中的类.但是,我想在所有模块中使用一些通用类(例如一些注释,实用程序,广播类,Dagger范围等).但这是我面临的问题
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
- 由于这些类包含在主模块
app
中,因此我无法 在我的data
和domain
中访问它们,因为这些模块不 取决于更高的层app
- 我在所有层中使用的任何库(例如:RxJava)都需要 包含在每个模块的
中build.gradle
- 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
作为解决方案,我想到了再添加一个android模块,例如common
,它将包含我所有的通用类以及我在所有模块中使用的库.
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.
我所有其他模块app
,domain
和data
都将这个模块作为依赖项.
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?
推荐答案
我们最近遇到了这个问题,因为我们过渡到多模块项目以进行重用,构建时间优化(不变的模块不会重新编译)等.核心目标是使您的app
模块尽可能小,因为每次都会重新编译.
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:
- 常见的
base-ui
模块包含主要的strings.xml
,styles.xml
等. - 其他前端模块(
profile
,dashboard
等)实现此base-ui
模块. - 将在 all 所有面向用户的模块中使用的库作为
api
而不是implementation
包含在base-ui
中. - 仅在 some 模块中使用的库仅作为依赖关系添加在这些模块中.
- 该项目也大量使用了数据同步等功能,因此也有遵循相同逻辑的
base-data
,dashboard-data
等模块. -
dashboard
功能模块取决于dashboard-data
. -
app
模块仅取决于功能模块,dashboard
,profile
等.
- 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.
我强烈建议您事先勾勒出您的模块依赖流程,最后我们得到了大约15个左右的模块,所有模块都经过严格组织.在您的情况下,您提到它已经是一个很大的应用程序,因此我想app
和domain
一样都需要从其中提取功能模块.记住,小的模块=更少的代码可以重新编译!
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!
在确保在所有子模块上使用相同版本的应用程序(buildType
,flavors
)时,我们遇到了一些问题.本质上,所有子模块都必须具有与app
模块相同的flavor
和buildType
定义.
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!
在评论讨论之后,这是一个示例图(不幸的是,它很曲折,但足以说明该概念.请注意,将api
和implementation
进行区分是一个不错的下一步):
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):
这篇关于如何在模块化Android应用程序中共享依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!