Gradle for Android 第三章:依赖管理

来源:互联网 发布:淘宝评论手机壳好评 编辑:程序博客网 时间:2024/04/30 10:21

  依赖管理是Gralde的亮点之一。在最理想的情况下,你只需要在构建文件中加入一行代码,Gradle就会从远程资源库中下载好依赖库,并保证里面的类在你的项目都可用。更甚者,如果你的项目的一个依赖还有它自己的依赖,Gradle依然能很好的解决。这种依赖的依赖,我们称之为transitive dependencies(传递依赖)。
  在本章我们会了解依赖管理的概念,并介绍在Android项目中添加依赖关系的几种方法。主要有以下几点内容:

  • 资源库
  • 本地依赖库
  • 依赖关系

1.资源库

  我们在讲依赖时,通常指的是外部依赖,如其他开发者提供的库。手动管理依赖十分麻烦。你需要定位库文件,下载JAR文件,把它复制到项目中,再引用它。通常这些JAR文件的名字中没有版本信息,所以你需要自己去添加,这样才能知道什么时候去更新。同时,你还要把这些库文件都放到资源控制系统(译者:笔者指的应该是SVN,git等)中去,这样你团队中的其他人才能使用它,而不需要再去手动地下载了。
  使用资源库就可以解决这个问题。资源库可以看作是一个文件集。而Gradle默认不会为你的项目添加任何资源库,所以你需要在repositories 域中去添加。如果你使用的是Android Studio,这一步已经完成了。在上一章,我们简单的提到过repositories 域:

repositories {    jcenter()}

  Gradle支持三种资源库:Maven,Ivy,和静态文件或静态目录。在构建的执行阶段,Gradle就会去资源库获取依赖库。Gradle还会做好缓存,所以一个指定版本的依赖库只会被下载一次。
  一个依赖库有三个标识元素:群组、名称和版本。群组定义了开发这个库的组织。名称则是依赖库的唯一标识符。版本当然就顾名思义了。有了这三个元素,依赖库就可以用下面的方式来声明了:

dependencies {    compile 'com.google.code.gson:gson:2.3'    compile 'com.squareup.retrofit:retrofit:1.9.0'}

  以上是简写形式,完整形式应该是:

dependencies {    compile group: 'com.google.code.gson', name: 'gson', version: '2.3'    compile group: 'com.squareup.retrofit', name: 'retrofit',version: '1.9.0'}

提示:其实依赖库的名称是必填的,而群组和版本是可选的。但还是建议清楚的写明群组和版本,以确保其不会自动更新,那会导制构建中断的。

1.1 预配置资源库

  为了方便,Gralde已经预先配置了三个Maven资源库:JCenter、Marven Central和本地Maven资源库。要把它们添加到构建脚本中,只需要以下三行:

repositories {    mavenCentral()    jcenter()    mavenLocal()}

  Maven Central和JCenter是两个知名的线上资源库。不需要同时使用它们两个,而且通常推荐使用JCenter,这也是Android Studio创建Android项目时的默认资源库。JCenter是Maven Central的父集,而且它能支持HTTPS,而后者不能。
  而本地Maven资源库是你已使用过的依赖库的本地缓存,而且也可以在其中添加你自己的依赖库。它的默认保存在主目录下的.m2 文件夹中。在Linux和Mac OS X中,地址是~/.m2,在Windows中则是%UserProfile%\.m2
  除了这些预配置的资源库,你也可以添加其他公共的,甚至是私有的资源库。

1.2 远程资源库

  有些组织开发出了有趣的插件或库之后,喜欢把它们放在自己的Maven或Ivy服务器中,而不会公布到Maven Central或JCenter。要在你的构建中添加这些资源库,只需要在maven 域中加入URL就可以了:

repositories {    maven {        url "http://repo.acmecorp.com/maven2"    }}

  Ivy资源库也同理。Apache Ivy是Ant世界中流行的依赖管理器。与添加Maven资源库的格式相同,只需要要ivy 域中加入URL,Gradle就可以支持这些资源库了:

repositories {    ivy {        url "http://repo.acmecorp.com/repo"    }}

  如果你的团队使用的是自己的资源库,并且为了安全,需要证书才能访问,可以这样做:

repositories {    maven {        url "http://repo.acmecorp.com/maven2"        credentials {            username 'user'            password 'secretpassword'        }    }}

  添加私有Ivy资源库的方法也是一样的,用同样的格式加入credentials 域就可以了。
注意:直接在构建配置文件中存储你的证书是不明智的。构建配置文件是不加密的,而且会同步到资源管理系统中。正确的做法应该是使用一个单独的Gradle属性文件,这点我们在第二章讲过。

1.3 本地资源库

  你还可以使用自己硬盘中的本地Maven和Ivy资源库。想要把它们添加到构建中,只需要配置其本地地止的URL就可以了:

repositories {    maven {        url "../repo"    }}

  新的Android项目默认依赖Android Support Library。当你用SDK manager来安装Google资源库时,有两个Maven资源库会在硬盘的* ANDROID_SDK/extras/google/
m2repository and ANDROID_SDK/extras/android/m2repository* 目录下创建。Gradle会在这里获取Google提供的库,如Android Support Library和Google Play Services。
  你也可以添加资源库的常用地址,用flatDirs 域:

repositories {    flatDir {        dirs 'aars'    }}

  等我们讲到库项目的时候,会用一个例子来讲解这个如何使用。

2.本地依赖库

  某些情况下,你可能还是需要手机下载JAR文件或本地库。可能你想要创建自己的库,好在多个项目里复用,又不想把它们发布到公共或私有资源库中。在这些情况下,就不能做用在线资源库了,你需要用不同的方法来添加依赖。我们会介绍如何使用文件依赖,如何添加本地库,如何在你的项目中添加库工程。

2.1 文件依赖

  要添加对JAR文件的依赖,你可以用Gradle提供的files 方法,如下所示:

dependencies {    compile files('libs/domoarigato.jar')}

  如果你有很多个JAR文件,这样做就很繁琐了,所以最好一次添加整个文件夹:

dependencies {    compile fileTree('libs')}

  一个新建的Android项目默认会有一个libs文件夹,它会被声明用来作为依赖。如果不想依赖文件夹中所有的文件,可以使用过滤器,而只依赖JAR文件:

dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])}

  这意味着在Android Studio中创建的任何Android项目,你都可以把JAR丢到libs文件夹中,它都会被自动编译到APK中去。

2.2 本地库

  用C或C++写的库可以编译成指定平台的本地代码。这些库通常都是.so文件,可以用到所有平台。Android插件默认支持本地库,你只需要在模块目录下建一个jniLibs 目录,并为每个平台建一个子目录。然后把.so文件丢到对应的目录中就可以了。
  文件结构如下:

app├── AndroidManifest.xml└── jniLibs       ├── armeabi       │     └── nativelib.so       ├── armeabi-v7a       │     └── nativelib.so       ├── mips       │     └── nativelib.so       └── x86       └── nativelib.so

  如果这种方式没有用,你可以自己在构建文件中设置路径:

android {    sourceSets.main {        jniLibs.srcDir 'src/main/libs'    }}

2.3 库工程

  如果你希望共享一个使用了Android API,或引用了Android资源的库,你就需要创建一个库工程。库工程一般和应用项目差不多。你可以用同样的task来构建和测试库工程,而且库工程也可以有不同的构建变体。不同的是生成的文件,应用项目会生成一个可以安装并运行在Android设备上的APK,而库工程会生成一个.aar 文件。这个文件就可以用作Android应用项目的库。

2.3.1 创建和使用库工程模块

  不同与添加Android应用插件,在构建脚本中应该以如下方式添加Android库插件:

apply plugin: 'com.android.library'

  有两种方法可以在你的应用中添加库工程。一种是做为项目的一模块引入;另一种则是创建.aar 文件,这种方式可以让其在多个应用中复用。
  如果你将库工程设置为项目的一个模块,那你需要在模块中加入settings.gradle 文件,并使其作为应用模块的依赖。配置文件如下:

include ':app', ':library'

  此时,这个库模块叫作library,同时它对应一个同名的文件夹。想要在Android模块中使用该库,需要要Android模块的build.gradle 文件中加入依赖:

dependencies {    compile project(':library')}

  这会将库工程的输出文件引入到应用模块的环境变量中去。我们会在第五章详细介绍该方法。

2.3.2 使用 .aar文件

  如果你希望你所创建的库可以在不同的Android应用中复用,你可以构建一个.aar 文件,并将其作为依赖引入你的项目。库的构建完成后,会在模块目录的build/output/aar/ 文件夹中生成 .aar 文件。想要依赖这个 .aar 文件,你需要在应用模块中分创建一个文件夹,把 .aar 文件复制到里面,并把这个文件夹作为资源库引入:

repositories {    flatDir {        dirs 'aars'    }}

  现在你就可以引入该文件夹中的任何文件来作为依赖了:

dependencies {    compile(name:'libraryname', ext:'aar')}

  这是告诉Gradle,去寻找以 .aar 结尾的某个具体名称的库。

3.依赖关系

  有几个依赖关系相关的概念理解起来很有趣,即使你现在可能还用不到。其中一个配置相关的概念,可以解释整章中我们一直在用的依赖关系中的compile 关键字。

3.1 配置项

  有时你可能需要使用适配特定设备的SDK,例如某个供应商提供的蓝牙SDK。为了能编译这些代码,你需要在你的编译环境中加入这个SDK。但是你没必要把SDK导入到APK中,因为设备中已经有SDK了。这里就涉及到依赖关系配置。
  Gradle把依赖关系都集中到配置项中,并且都用文件集的形式来命名。以下就是Android应用或库的标准配置项:

  • compile
  • apk
  • provided
  • testCompile
  • androidTestCompile

  compile 配置项是默认的,其中包含了编译主应用所需的全部依赖关系。这个配置项里的所有依赖,不仅会被添加到编译环境中,还会添加到生成的APK中。
  apk 配置项中的依赖就只会被添加到APK中,耍不会被添加到编译环境中。而provided 配置项就正好相反,其依赖不会被添加到APK中。而且这两个配置项只能打包JAR依赖,如果添加库工程则会报错。
  最后,testCompileandroidTestCompile 配置项用来添加用于测试的外部库。当运行测试相关的task时,这两个配置项才会被用到,在加入测试框架时,比如JUnit或Espresso,这两个配置项很有用。而这些框架只会存在于测试APK中,不会在发布的APK中。
  除了这些标准的配置项,Android插件还会为每一个构建类型生成配置项,让你可以为debugCompilereleaseProvided 等这项配置项添加依赖。例如,你可以只在你的开发构建中添加一个日志框架。在第四章我们会详细介绍。

3.2 版本控制

  版本控制是依赖管理中重要的部分。资源库中的依赖,如JCenter,都会遵循一套叫做semantic versioning的版本控制规则。在这个规则中,版本号都是“major.minor.patch”这样的格式,而这些版本号都按以下规则增长:

  • major:主版本号,有不兼容的API修改时增加
  • minor:副版本号,有向下兼容的功能加入时增加
  • patch:补丁号,有bug修复时增加

3.3 动态版本

  在某些情况下,你可能希望在每次构建应用或库的时候,都使用最新版本的依赖库。要实现这一点,最好的方法就是使用动态版本。添加动态版本有很多种方式,下面是一些例子:

dependencies {    compile 'com.android.support:support-v4:22.2.+'    compile 'com.android.support:appcompat-v7:22.2+'    compile 'com.android.support:recyclerview-v7:+'}

  第一行,我们告诉Gradle去获得最新的补丁版本。第二行,我们会获取最新的副版本,且副版本号最少为2。最后一行,Gradle会获取最新版本的库。
  在使用动态版本时你需要格外小心。如果你允许Gradle获取最新版本,这个版本可能是不稳定的,这就会导致构建失败。更糟糕的是,你可能会在构建服务器和你自己的机器上得到不同版本的依赖,从而导致应用的不一致。
  当你在你的构建文件中使用动态版本时,Android Studio会警告你可能产生的问题,如下图如示:
dynamic versions warning

4.Android Studio的使用

  添加新的依赖最简单的方法就是使用Android Studio的Project Structure对话框。点击File –> Dependencies打开对话框,就可以得到当前依赖关系的概况:
Project Structure
  在这个对话框中,你可以点击绿色的+按钮来添加新的依赖。你可以添加另的模块,甚至可以搜索JCenter中的库:
Dependencies
  使用Android Studio,可以更方便的看到项目依赖关系的概况和添加新的库。你不必手机的在build.gradle 文件中写代码,而且可以轻易的在IDE中直接搜索JCenter。

5.总结

  本章中,我们介绍了在Android项目中添加依赖的几种方法,学习了资源库及其使用形式,以及在不使用资源库的情况下如何依赖文件。
  同时还了解了关于依赖的一些重要概念,分别是配置项,semantic versioning版本控制和动态版本。
  我们还提到了几种场景的构建变体,而在下一章,我们终于要介绍什么是构建变体,以及它有什么用。构建变体可以使应用的开发,测试和分发变得更简单。理解了变体的工作原理,可以大大提高你开发和分发应用的速度。

0 0