如何在模块化Android应用程序中共享依赖项 [英] How to share dependencies in a Modularized Android App

查看:228
本文介绍了如何在模块化Android应用程序中共享依赖项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个以模块化方式进行架构的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是其他模块所不依赖的模块,它是应用程序的主要模块.较低级别的模块domaindata不依赖于App模块,其中App模块包括datadomain模块.我在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模块可以使用datadomain模块中的类.但是,我想在所有模块中使用一些通用类(例如一些注释,实用程序,广播类,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中,因此我无法 在我的datadomain中访问它们,因为这些模块不 取决于更高的层app
  • 我在所有层中使用的任何库(例如:RxJava)都需要 包含在每个模块的build.gradle
  • Since these classes are contained in the main module app, I cannot access these in my data and domain, because those modules do not depend on the higher layer app
  • 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.

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

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.xmlstyles.xml等.
  • 其他前端模块(profiledashboard等)实现此base-ui模块.
  • 将在 all 所有面向用户的模块中使用的库作为api而不是implementation包含在base-ui中.
  • 仅在 some 模块中使用的库仅作为依赖关系添加在这些模块中.
  • 该项目也大量使用了数据同步等功能,因此也有遵循相同逻辑的base-datadashboard-data等模块.
  • dashboard功能模块取决于dashboard-data.
  • app模块仅取决于功能模块,dashboardprofile等.
  • A common base-ui module contains the primary strings.xml, styles.xml etc.
  • Other front-end modules (profile, dashboard, etc) implement this base-ui module.
  • Libraries that will be used in all user-facing modules are included in base-ui, as an api instead of implementation.
  • 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 on dashboard-data.
  • The app module depends only on feature modules, dashboard, profile, etc.

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

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!

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

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 flavors and buildTypes 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!

在评论讨论之后,这是一个示例图(不幸的是,它很曲折,但足以说明该概念.请注意,将apiimplementation进行区分是一个不错的下一步):

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆