适用于Android,AAR和条件依赖项的Gradle

 od扒着井沿的牛蛙 发布于 2023-02-06 13:35

简短形式:为AAR组织代码/ POM有哪些方法,这样使用该AAR的应用程序只有他们实际需要的依赖项?

长形式:

假设我们有一个依赖于打包为AAR(L)的Android库项目的应用程序.

L包含多个类,任何给定的应用程序(如A)都只使用这些类的子集.例如:

L可能包含Fragment本机API Level 11片段,反向移植的片段和ActionBarSherlock风格片段的实现

L可包含Activity定期活动,实施FragmentActivity,ActionBarActivity和ActionBarSherlock味活动

L可以通过LocalBroadcastManagerSquare's Otto和greenrobot的EventBus举办活动

等等

正如我所看到的,这些案例有两个主要共性:

    应用程序通常只关心某些类.例如,使用Otto的应用程序不关心引用greenrobot的EventBus的代码,或者使用的应用程序ActionBarActivity不关心ActionBarSherlock.

    如果AAR是repo中的工件,则应用程序将不关心构建AAR所需的所有可能的上游依赖项.例如,使用本机API Level 11片段的应用程序将不需要support-v4或者actionbarsherlock,即使AAR本身需要它们来构建AAR

如果我们使用JAR而不是AAR并转储依赖关系管理,这是相当简单的.构建JAR将具有编译时依赖性(例如,support-v4).但是,使用该JAR的应用程序可以跳过这些依赖项,只要这些应用程序不使用真正需要这些依赖项的类,生活就会很好.

但是,我很难看到如何使用build.gradle文件中指定的AAR和Maven工件完成相同的操作.如果L有一个dependencies引用上游依赖项的块,那么当应用程序依赖于L时,应用程序将依次下载这些依赖项.

我相当肯定的一个解决方案是将L分成几个库.例如,使用片段场景,我们可以:

L1,包含本机API Level 11版本的片段的实现,以及其他场景所需的任何公共代码.该库没有上游依赖项.

L2,包含使用Android Support包的片段backport的实现.L2会依赖于L1和on support-v4.

L3,包含使用Sherlock风格片段的实现.L3将依赖于L1和actionbarsherlock.

然后,应用程序将选择是依赖于L1,L2还是L3,因此只会获得必要的上游依赖项(如果有的话).

我的问题是:这是最好的解决方案吗?或者Gradle for Android,AAR和Maven风格的工件世界还有什么东西可以让应用程序依赖单个L?我担心库的组合爆炸可能会处理各种上游依赖关系.我也很关心,其实古怪的应用程序需要多个实现,我们是否能够可靠地确定对那些依赖包(例如,根据L1和L2的应用程序,因为这是该应用程序的作者认为,应用程序的需求).

我知道应用程序有一些方法可以阻止 排除依赖关系(请参阅Joseph Earl对语法的回答),因此应用程序可以依赖于L但是actionbarsherlock如果不需要则阻止上游依赖关系.虽然这可行,但对于我是L的作者的情况,我宁愿采用L1/L2/L3方法,因为这看起来更清晰.

还有其他建议吗?

2 个回答
  • 在您的应用程序项目中可以排除Gradle中的传递依赖项(例如,如果您知道它将不被使用,则排除包含ActionBarSherlock),例如

     dependencies {
       compile('org.hibernate:hibernate:3.1') {
         // Excluding a particular transitive dependency:
         exclude module: 'cglib' //by artifact name
         exclude group: 'org.jmock' //by group
         exclude group: 'org.unwanted', module: 'iAmBuggy' //by both name and group
       }
     }
    

    您还可以通过ProGuard(和DexGuard)来压缩和删除未使用的代码.

    Gradle还不支持将依赖项标记为Maven所做的可选项(可以在库项目中使用).

    2023-02-06 13:36 回答
  • 我不知道有任何依赖管理功能可以帮助解决这个问题.

    拥有一个具有许多依赖项的单个库以及删除不需要的依赖项的能力可能会有效,但是会出现一些问题:

    您必须依赖L的用户来删除正确的依赖项.

    您将在库中拥有使用Proguard轻松剥离的课程.Proguard不会删除任何扩展Fragment/Activity/etc的东西,L应该提供一个proguard规则文件,不删除扩展支持Fragment/Activity/etc的类......这将使删除不需要的类变得困难.

    某些实现可能有额外的资源,现在我们无法删除不需要的资源.

    我认为拆分库是正确的做法,但是在我们在图书馆项目中有风味之前,这将是复杂的.一旦我们有了这个,我认为处理起来会容易得多.你不会有基础L1和L2/L3扩展它.相反,您将拥有一个生成不同变体的库,每个变体都有自己的依赖项.

    对于风味尺寸,您可以处理支持库与事件库组合,但如果添加更多尺寸,您最终会获得一些爆炸.

    多变量库的优点是,在不引入更多子库的情况下,跨变体子集共享代码要容易得多.您还可以在主代码和风格之间进行双向引用,这取决于L1,您不能使用L2/L3.

    至于支持Ant/Eclipse,这肯定会变得复杂.我肯定会无视Ant.如果有人只关心命令行构建,他们应该已经转移到Gradle.至于Eclipse,我们在某些时候会得到Gradle支持,但是我知道你是否等不及了.

    2023-02-06 13:38 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有