繁体   English   中英

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

[英]Gradle: pros/cons adding dependencies

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

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

在开发Android项目的过程中,我经常遇到一些很棒的库,它们都是我一直在寻找的精确解决方案。 但是,正如我所需要的只是这些特定库所提供的内容的一小部分,我担心如果将它们添加为Gradle dependencies是一种过度杀伤力


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

是否添加依赖项:

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

  2. 增加release-apk和debug-apk的大小,增加依赖的大小?

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

依赖类型:

外部模块依赖:

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

项目依赖:

依赖于同一构建中的另一个项目。

文件依赖:

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

客户端模块依赖:

依赖于外部模块,其中工件位于某个存储库中,但模块元数据由本地构建指定。 当您想要覆盖模块的元数据时,可以使用这种依赖关系。

Gradle API依赖:

依赖于当前Gradle版本的API。 在开发自定义Gradle插件和任务类型时,可以使用此类依赖关系。

本地Groovy依赖:

依赖于当前Gradle版本使用的Groovy版本。 在开发自定义Gradle插件和任务类型时,可以使用此类依赖关系。

优点添加依赖项:

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

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

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

  • 在线可用性依赖

  • require sdk库已与项目同步进行编译。

缺点:

因此,它没有任何缺点,但在初始阶段添加依赖项时我们必须同步它,这比简单地拖放jar文件需要一些时间。

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

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

增加release-apk和debug-apk的大小,增加依赖的大小?

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

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

肯定会有一种情况,例如你的情况下只使用一个库的子集。因此在这种情况下,启用ProGuard优化字节码级别,内部和跨方法的执行分析,以帮助使您的应用程序更小,运行更快,没有过度杀伤。

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

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

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

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

在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)

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

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

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

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

是否只提取您需要的代码

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

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

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

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

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

我认为这个问题并不是非常依赖于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,除非它是一个“玩具项目”。

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

1. Gradle子项目

dependencies {
  compile project(':foobarlib')
}

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

如果您希望进行更改,则可以执行此操作,并且可以看到更改所需的全部内容是根gradle项目的gradle编译。

2. Android库项目

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

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

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

哪一个更好?

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

Gradle依赖是一种矫枉过正

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

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

事实并非如此

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

对APK大小的担忧

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

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

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

将库添加为模块依赖项

添加为库模块将通过获取依赖关系所需的下载时间加快构建过程,您可以通过在Android工作室中为Gradle启用脱机同步来轻松实现。

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

1. slow down compilation time at a noticeable rate?

简答:是的。

长答案:我们目前正在项目中使用Gradle ,并且在我所经历的兼容时间方面存在一个值得注意的 差异 如果您的项目具有多模块依赖项,则尤其如此。 另外还有一个事实,如果你继续添加很多依赖项只是为了使用每一个中的一堆类,你最终会遇到非常有名的:

Too many references: 66539 error; max is 65536.

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

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美分。 希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM