【发布时间】:2014-01-23 03:50:14
【问题描述】:
短格式:有哪些方法可以组织 AAR 的代码/POM,以便使用该 AAR 的应用程序只有它们实际需要的依赖项?
长格式:
假设我们有一个依赖于一个打包为 AAR (L) 的 Android 库项目的应用。
L 包含多个类,任何给定的应用程序(如 A)只会使用这些类的子集。例如:
L 可能包含
Fragment原生 API 级别 11 片段、反向移植片段和 ActionBarSherlock 风味片段的实现L 可能包含用于常规活动的
Activity实现、FragmentActivity、ActionBarActivity和 ActionBarSherlock 风格的活动L 可以通过
LocalBroadcastManager、Square 的 Otto 和 greenrobot 的 EventBus 引发事件等等
在我看来,这些案例有两个主要的共同点:
应用程序通常只关心某些类。例如,使用 Otto 的应用不会关心引用 greenrobot 的 EventBus 的代码,或者使用
ActionBarActivity的应用不会关心 ActionBarSherlock。如果 AAR 是存储库中的工件,应用程序将不会关心构建 AAR 所需的所有可能的上游依赖项。例如,使用原生 API 级别 11 片段的应用将不需要
support-v4或actionbarsherlock,即使 AAR 本身需要它们来构建 AAR
如果我们使用 JAR 而不是 AAR 并转储依赖项管理,这相当简单。构建 JAR 将具有编译时依赖项(例如,support-v4)。但是,使用该 JAR 的应用程序可以跳过这些依赖项,只要这些应用程序不使用真正需要这些依赖项的类,生活就很好。
但是,我很难看到如何使用 build.gradle 文件中指定的 AAR 和 Maven 工件来完成相同的事情。如果 L 有一个 dependencies 块引用上游依赖项,则当应用程序依赖 L 时,应用程序将依次下载这些依赖项。
我相当确定可行的一个解决方案是将 L 拆分为多个库。例如,使用片段场景,我们可以:
L1,其中包含原生 API 级别 11 版本片段的实现,以及其他场景所需的任何通用代码。该库将没有上游依赖项。
L2,其中包含使用 Android 支持包的片段反向移植的实现。 L2 将依赖于 L1 和
support-v4。L3,其中包含使用 Sherlock 风格片段的实现。 L3 将依赖于 L1 和
actionbarsherlock。
然后,应用会选择是否依赖 L1、L2 或 L3,因此只会获得必要的上游依赖项(如果有的话)。
我的问题是:这是最好的解决方案吗?或者在 Gradle for Android、AAR 和 Maven 风格的工件的世界中是否有其他东西可以让应用程序依赖于单个 L?我担心库可能会组合爆炸以处理上游依赖项的各种组合。我还担心实际上确实需要多个实现的奇怪应用程序以及我们是否可以可靠地指定这些依赖项(例如,一个依赖于 L1 和 L2 的应用程序,因为那是那个应用程序的作者认为应用需要)。
我知道应用有办法block exclude 依赖项(请参阅 Joseph Earl 对语法的回答),因此应用可以依赖 L 但随后会阻止actionbarsherlock 上游依赖项(如果不需要)。虽然这可行,但对于我是 L 的作者的情况,我宁愿采用 L1/L2/L3 方法,因为这样看起来更简洁。
还有其他建议吗?
【问题讨论】:
-
我投票支持分离的库,即使它在支持方面很痛苦。 L1 无需提及,因为 L3 对 L1 具有传递依赖
-
AAR的缩写代表什么? -
@gunar: Android 存档
标签: android maven gradle android-gradle-plugin