如何在模块化Android应用程序中共享依赖项

时间:2019-01-09 06:24:23

标签: java android android-gradle clean-architecture android-architecture

我有一个以模块化方式构建的Android项目。我通过按照clean Architecture在多个Gradle模块之间划分源代码来对项目进行模块化。

这是应用程序的结构。

enter image description here

此层次结构中的最高模块App是其他模块所不依赖的模块,它是应用程序的主要模块。下级模块domaindata不依赖于App模块,其中App模块包括datadomain模块。我在app模块的build.gradle中添加了以下代码

    implementation project(':domain')
    api project(':data')

现在,我在维护每个模块之间的依赖性时遇到了一些问题。由于每个都是独立的android模块,因此每个都有自己的build.gradleApp模块可以使用datadomain模块中的类。但是,我想在所有模块中使用一些通用类(例如一些注释,实用程序,广播类,Dagger范围等)。但这是我面临的问题

  
      
  • 由于这些类包含在主模块app中,因此我无法   在我的datadomain中访问它们,因为这些模块不   取决于高层app
  •   
  • 我在所有层中使用的任何库(例如:RxJava)都必须是   包含在每个模块的build.gradle
  •   

为此,我想到了一个解决方案,我想再添加一个Android模块,例如common,它将包含我所有的通用类以及我在所有模块中使用的库。

我所有其他模块appdomaindata都将这个模块作为依赖项。

implementation project(':common')

因此,所有全局库和类都将添加到此模块,并且每个单独的模块将仅具有特定于模块的类。

这是一个好方法吗?还是有什么办法可以有效地解决这个问题?

1 个答案:

答案 0 :(得分:9)

我们最近遇到了这个问题,因为我们过渡到多模块项目以进行重用,优化构建时间(不重新编译未更改的模块)等。您的核心目标是使app模块尽可能小尽可能,因为每次都会重新编译。

我们使用了一些通用原则,这些原则可能会对您有所帮助:

  • 常见的base-ui模块包含主要的strings.xmlstyles.xml等。
  • 其他前端模块(profiledashboard等)实现此base-ui模块。
  • 所有所有面向用户的模块中使用的库都以base-ui而不是api的形式包含在implementation中。
  • 仅在 some 模块中使用的库仅作为依赖关系添加在这些模块中。
  • 该项目也大量使用了数据同步等功能,因此,遵循相同的逻辑,还有base-datadashboard-data等模块。
  • dashboard功能模块取决于dashboard-data
  • app模块仅取决于功能模块dashboardprofile等。

我强烈建议事先勾勒出您的模块依赖流程,最后我们得到了大约15个左右的模块,所有模块都经过严格组织。就您的情况而言,您提到它已经是一个很大的应用程序,因此我想appdomain一样都需要从其中提取功能模块。记住,小的模块=更少的代码可以重新编译!

在确保在所有子模块上使用相同版本的应用程序(buildTypeflavors)时,我们遇到了一些问题。本质上,所有子模块都必须具有与flavor模块相同的buildTypeapp定义。

另一方面,多模块开发确实使您思考依赖关系,并强制功能之间严格分离。您可能会遇到一些以前从未考虑过的意外问题。例如,只需显示应用程序的版本suddenly complicates(免责声明:我的文章)。

This article也帮助我们决定了方法。您链接的文章似乎也是很好的参考资料,我希望它在我们过渡时就已经存在!

在讨论讨论之后,这是一个示例图(不幸的是,但足以说明问题。请注意,在apiimplementation之间进行区分是一个不错的下一步): module dependency diagram