Gradle:添加依赖项的优点/缺点

时间:2015-05-31 21:42:35

标签: android gradle dependencies android-gradle android-library

build.gradle中添加依赖项有哪些优点/缺点,而不是将它们添加为依赖库?

dependencies {
    compile project(':library')
    ...
    compile 'com.stackoverflow.android:some-great-library:1.0'
    ...
}

在开展Android项目的过程中,我经常遇到一些很棒的图书馆,其中包含我一直在寻找的精确解决方案。但是,由于我所需要的只是这些特定图书馆提供的内容的一小部分,我担心如果将Gradle dependencies添加为 overkill

根据@ CommonsWare的评论,我有更具体的问题。

是否添加依赖项:

  
      
  1. 以明显的速度减慢编译时间?

  2.   
  3. 增加release-apk和debug-apk的大小,与添加的依赖项的大小一样多吗?

  4.   

9 个答案:

答案 0 :(得分:7)

在Gradle中,依赖关系被分组为配置作为依赖关系配置。外部依赖关系是对在当前版本之外构建的某些文件的依赖关系,并存储在某种类型的存储库中,例如Maven central或公司Maven或常春藤存储库,或本地文件系统中的目录。

依赖类型:

外部模块依赖:

  

某个存储库中对外部模块的依赖。

项目依赖:

  

对同一版本中另一个项目的依赖。

文件依赖:

  

依赖于本地文件系统上的一组文件。

客户端模块依赖:

  

对工件所在的外部模块的依赖性   在某些存储库中,但模块元数据由本地指定   建立。当你想要覆盖时,你使用这种依赖   模块的元数据。

Gradle API依赖:

  

对当前Gradle版本的API的依赖性。你用它   在开发自定义Gradle插件时的依赖性   任务类型。

本地Groovy依赖:

  

对当前Gradle版本使用的Groovy版本的依赖性。   在开发自定义Gradle时使用这种依赖关系   插件和任务类型。

优点添加依赖项:

  • 在Gradle中,您只需声明依赖项的“名称”,然后 其他层确定从哪里获取这些依赖项。

  • 在SubProject中可以进行代码更改。

  • 清除直接依赖关系,包括使用过的库的版本
    管理明确的间接依赖关系(即使用的库使用另一个 图书馆 - POM文件){来自用户Robert Halter)。

  • 依赖在线可用性

  • require sdk库已经与项目同步了 汇编

<强>缺点:

  

因此,在添加时的初始阶段没有任何缺点   依赖我们必须同步它,这需要一点时间而不是简单   拖延删除jar文件。

以明显的速度减慢编译时间?

  

不,因为这些库仅在同步时编译。

增加release-apk和debug-apk的大小,与添加的依赖项的大小一样多?

  

不,但实际上是,因为它只需要构建的大小   文件(二进制大小)几乎不增加字节大小或kb   几乎无法追溯。

所以当我们只需要使用特定库的一小部分时,最后将它们添加为Gradle依赖项是一种过度的做法吗?

  

肯定会出现像你这样的情况只能使用a   库的子集。在这种情况下,启用ProGuard进行优化   在字节码级别,内部和跨方法执行分析   有助于缩小您的应用程序并在没有过度杀伤的情况下更快地运行。

答案 1 :(得分:4)

主要关注你的Android应用程序大小。 许多方法或类可能会提高dex文件的64k限制,并且主要需要启用multi-dex或jumbo模式。如果你有非常过时的客户,这可能会给你带来一些兼容性问题。

有时你可能想要通过只提取你需要的类来解决它,但有时它并不容易。

如果启用了proguard,则可以系统地删除未使用的类。

答案 2 :(得分:3)

将第三方库的代码复制到您的项目会导致支持该项目的一些问题 如果您需要使用新版本的库,该怎么办? 如果您将其添加为依赖项,那么您需要的是在构建系统配置中更改版本号

答案 3 :(得分:3)

在Gradle Build Project中从子项目添加依赖项的优缺点是什么?

dependencies {
    compile project(':library')
}

<强>赞成

  • 可以在:库子项目中更改代码

<强>缺点

  • 自行管理:库子项目的版本

在Gradle Build Project中从版本化的从属库a添加依赖项的优缺点是什么?

dependencies {
    compile 'com.stackoverflow.android:some-great-library:1.0'
}

<强>赞成

  • 清除直接依赖关系,包括使用的库的版本
  • 清除管理的间接依赖关系(即使用的库使用另一个库 - POM文件)
  • 另一个人/小组管理图书馆的功能 - 您可以专注于自己的代码。

<强>缺点

是否将依赖项添加为:库子项目以显着的速率减慢编译时间?

  • 是的,它们也必须编译,因为它们位于子项目的源代码中
  • Gradle使用任务的输入/输出定义优化构建时间。在构建时查看UP-TO-DATE标记。

将依赖项添加为版本化依赖库是否会以显着的速率减慢编译时间?

  • 不,因为已经编译了库(.jar)。

添加依赖项是否会增加release-apk和debug-apk的大小,与添加的依赖项的大小一样多?

  • apk Size增加添加的依赖项的二进制大小(.jar = Zipped .class Files)。
  • (如果您启用了proguard,可以系统地删除未使用的类 - 来自用户phdfong)

答案 4 :(得分:2)

  

是否添加第三方库作为依赖

当程序在编译时或运行时使用此库中的某些代码时,您将声明对第三方库的依赖关系。这意味着在程序运行时必须可以访问第三方代码,因此它与您的程序一起打包。因此,应用程序大小增加,这是不希望的,因为许多用户不喜欢大型应用程序。当你的程序很小而且第三方库很庞大时,这也很荒谬。

  

是否将第三方库添加为模块

我从来没有这样做,但如果我理解正确,它与在项目中复制库相同,所以你可以修改它。如果使用发行版,则远程依赖项编译不会存在编译时差异。一切都与前一段相同,但此外您可以自由修改代码(如果第三方库许可证允许的话)。

  

是否仅提取您需要的代码

这是最好的解决方案,如果您只需要一些库中的方法,并且提取它们并不困难(再次,假设许可证允许这样做)。另一方面,如果您使用某些可靠的第三方功能并希望在项目中提取和修改它,您将来可能会面临维护问题(如果您决定迁移到新版本)。

  

是否添加依赖项:以明显的速度减慢编译时间?

使用正确的Gradle调整(在后台使用守护程序,使用并行处理),您不会发现典型项目中的任何重大变化。

  

添加依赖项:增加release-apk的大小   debug-apk,与添加的依赖项的大小一样多吗?

将依赖jar发送到dex进行字节码转换以及项目代码。就尺寸而言,这不是1:1的转换,所以答案是否定的。此外,ProGuard还有一些技巧可以最小化jar大小,Maven有一个plugin用于将所有相关的jar包装在一起,所以它们都可以被混淆。

答案 5 :(得分:2)

我认为这个问题并不是非常依赖Gradle,而是更多地依赖于“依赖关系管理工具”。

当然,有些情况下我们只需要一个库的子集。在这些情况下,必须导入整个依赖项可能不是最佳解决方案。

多少“矫枉过正”?显然这取决于项目的大小。由你来评估一个依赖可能有多大“过度杀戮”:例如,如果你只需要一个简单的函数而你导入一个3MB的库,可能是的,有点'过度杀伤!

此外,您必须考虑通常将“大”库划分为模块,因此您只能导入所需的模块。对于Android,如@phdfond所说,您可以使用ProGuard在构建时删除未使用的类,或者您可以使用Gradle手动排除它们:

//...      
sourceSets {
         main {
             java {
                 exclude '**/IDontWantThisClass.java'
             }
         }

但恕我直言,这种情况并不常见,你可以通过使用Gradle或其他“依赖管理工具”获得很多优势(请注意,在Gradle,Maven,ecc ......依赖管理只是其功能之一)。

例如,如果您使用Gradle一目了然,您就知道自己的依赖关系,并且可以轻松添加/删除它们,或只是更改数字以更新其版本。 您是否认为您的项目可以依赖于库B和C,而B和C都可以依赖于两个不同版本的lib D? Well Gradle也可以帮助你这样的情况。 我不能继续这里,因为我会偏离主题,但你可以找到很多关于这个工具的信息。

最后,我认为“依赖关系管理工具”最重要的“缺点”是最初的学习和设置时间。如果您从未使用像Gradle这样的工具,那么第一次将比拖放jar需要更多时间,因此我强烈建议您在项目中使用Gradle,除非它是“玩具项目”。

答案 6 :(得分:1)

我会说他们是根本不同的东西。

<强> 1。 Gradle子项目

dependencies {
  compile project(':foobarlib')
}

在第一种情况下,您依赖于Android子项目,这是您正在处理的gradle项目的一部分。您也可以将module称为Intellij这种类型的依赖关系。

如果您希望进行更改,您可以这样做,并且可以看到更改所需的全部内容是根草图项目的gradle编译。

<强> 2。 Android库项目

dependencies {
  compile 'com.example:foobarlib:2.1.0'
}

在第二种情况下,您所依赖的是artefact(即JARAAR格式的存档),而不是项目。这实际上是您的gradle项目的黑盒子。所有gradle都知道它包含项目所需的已编译类(以及AAR情况下的资源)。

如果您希望对库进行更改,首先需要找到相应的项目来编辑其源,编译项目并将新的人工制品发布到本地远程maven repository。最后,为了让您的项目能够查看在其他项目中所做的更改,您必须更新依赖项中声明的版本号,以便gradle知道它必须带来新发布的artefact。

哪一个更好?

当然,这取决于。只要想想图书馆是否有自己的感觉,或者它实际上只是你的应用程序的一个模块。正如您所看到的,如果您只是处理应用程序的模块,第二种方法会增加太多开销,而且在没有其他应用程序的情况下版本和分发这些更改也毫无意义。

答案 7 :(得分:1)

  

Gradle依赖是一种过度杀伤

好吧,如果您使用的是一些稳定的库,或者您对当前的库功能感到满意。此外,当库具有向后移植的依赖关系或具有一组功能或说您根本不需要的类时。

解决方案将从库中获取您所需的内容(仅当您确定它满足您的要求时)

  

而且它不是

如果您想对库进行自动更新和修复,则易于集成。许多图书馆都是每天制作和维护的,所以APK大小对我们来说并不重要,因为图书馆更新了,所以gradle导入很好。

  

对APK大小的担忧

gradle依赖可能有很多不相关的东西,你的应用程序不需要的后向支持,这最终会增加应用程序的大小,也会导致编译速度慢。

因此,如果库只有一个类或更少的类,您可以直接将它添加到某个包中的应用程序中。一个很好的例子是Google IO应用程序,其中一些库是不同的软件包。

您还可以控制调试或发布apk的内容,对于调试依赖项使用debugCompile,对于测试依赖项使用testCompile

  

将库添加为模块依赖

添加为库模块将通过获取依赖项所需的下载时间加快构建过程,您可以通过在Android Studio中为Gradle启用离线同步轻松实现这一过程。

如果您已经开发了一些私有库并且在整个项目中使用它,那么库模块也是如此,如果不是这样的话,您将在maven中心发布和维护库,并且更容易集成到通过gradle你自己的一组项目。

答案 8 :(得分:1)

1. slow down compilation time at a noticeable rate?

简答:是的。

冗长答案:我们目前在项目中使用Gradle,并且在我所经历的 complitaion 时间内存在值得尊重的差异。如果您的项目具有多模块依赖项,则尤其如此。另外更不用说如果你继续添加很多依赖项只是为了使用它们中的每一个类,你最终会遇到非常有名的:

Too many references: 66539 error; max is 65536.

在使用资源密集型库(例如gradle)时,我自己经历了很多次(mavenplay-services)。

2. `increase the size of release-apk and debug-apk, as much as the size of the added dependency?`

肯定会。与release-apk不同,因为你可以优化proguard到你想要的任何扩展。在debug-apk的情况下,我看到大小变化高达5-6 MB。

只需2美分。希望这会有所帮助。

相关问题