Gradle for Android-管理依赖

来源:互联网 发布:博罗县政府网络问政网 编辑:程序博客网 时间:2024/04/30 15:56

依赖管理是gradle的亮点之一。最好的情况是你所需要的全部只是添加一行代码到build文件中,而且gradle将会从远程库中下载依赖并确保你的项目可以使用它的类。gradle甚至更近一步。万一项目的依赖本身也有依赖,gradle会解决这些事情,做好一切。依赖的依赖叫做传递依赖。

本章主要介绍依赖管理的概念,以及多种添加依赖到项目中的方式。我们将要讨论的主题如下:

-库
-本地库
-依赖概念

当我们讨论依赖时,我们所指的是外部依赖,比如其他开发者提供的包。手动管理依赖是很麻烦的事。要先定位library,下载JAR文件,复制到项目中然后调用。通常这些文件名中并不包含版本信息,为了按时更新,需要主动添加。也要确保这些library被存储于源控制系统中,以便小组成员可以不用下载直接使用。
使用repositories可以解决如下问题。repository可被视作文件集合。默认情况下,gradle不会为项目定义任何repositories,所以你需要把它们添加到repositories块中。如果使用AS,会自动完成这些。在之前的章节里,我们简略地提到过repositories块,看起来如下:

repositories {    jcenter()}

gradle支持三种不同类型的repositories:Maven,Ivy和静态文件或目录。在build的执行阶段,从repositories中获取dependencies。gradle也会保存到本地缓存,所以一个dependency版本仅需下载一次。

一个dependency被三种元素标识:group,name和version。group指定了library的创建组织并采用反域名法命名。name就是library的唯一标识。version指定了要使用的library的版本。使用这三种元素,在以下结构的dependencies块中就会声明一个dependency:

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

有一种完整的groovy映射符号速记法,如下:

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

对于一个dependency,唯一要求的字段是name。group和version都是可选的。尽管如此,为了清晰性和确定library没有自动更新(可能会导致build中止),还是建议把group和version添加上。

预配置库

为了你的方便,gradle预配置了三种Mavan库:JCenter,Maven Central和本地Maven库。为了把它们添加到build脚本中,需要加入以下代码:

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

Maven Central和JCenter是两个非常出名的在线库。没有理由同时使用这两种,系统建议使用JCenter,这也是AS项目中默认的repository。JCenter是Maven Central的超集,二者切换时,可以完全保留原先定义的dependencies。另外,JCenter也支持HTTPS,而Maven Center则不行。

本地的Maven repository是你使用过的所有dependencies的本地缓存,而且也可以添加你自己的dependencies。默认情况下,repository可以在一个叫做.m2的文件的home目录下找到。在Linux或Mac OS X中,路径是~/.m2。在windows中,路径是%UserProfile%.m2。

除了这些预配置的repositories,也可以增加其他的公共或私有的repositories。

远程库

有些组织创建了一些非常有趣的插件或包,代之放到Maven Central或JCenter,他们更愿意把它放到自己的Maven或Ivy服务器上。为了把这些库添加到你的build中,需要把URL添加到maven块中。

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

Ivy repositories亦是如此。Apache Ivy是Ant界中非常流行的依赖管理。Gradle也支持Maven repositories使用的库。添加repository URL到ivy块中,如下:

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

如果你的组织运行自己的库,可能会很安全,而且也需要证书访问。这里展示如何为repository添加证书:

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

对于Maven和Ivy类似。可以使用相同的格式在你的Ivy repository配置中添加credentials块。

存储证书:在build配置文件中存储证书并不是个好想法。build配置文件是纯文本的,而且会被纳入源控制系统的检查下。一个好主意就是使用一个独立的gradle属性文件,正如我们再第二章看到的那样

本地库

可以在硬盘或网络驱动上运行Maven和Ivy repositories。为了把这些加入到build中,需要在驱动中配置相对或绝对的URL路径。

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

新的Android项目默认有一个Android Support Library依赖。当使用SDK manager安装Google库的时候,会在你的硬驱ANDROID_SDK/extras/google/m2repository和ANDROID_SDK/extras/android/m2repository上创建两个Maven repositories。这也是gradle获取google提供的包的位置,例如Android Support Library和Google Play Services。

也可以使用flatDirs增加一个常规目录作为repository。这可以使你在dependency块中从该目录下添加文件。

repositories {    flatDir {        dirs 'aars'    }}

本章之后,当我们讨论library项目时,会学习怎么使用的例子。

本地依赖

有些情况下,你可能需要手动下载JAR文件或native。可能你想要创建能在好几个项目中使用的自己的包,而不用把它放到公共或私有的库中。在这些情况下,不可能使用任何在线资源,而且你要使用不同的方式添加依赖。我们会描述如何使用文件依赖,添加native库以及如果添加library项目到你的项目中。

文件依赖

增加JAR文件作为依赖,可以使用gradle提供的files方法。看起来如下:

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

如果添加大量JAR文件可能过于冗长,所以添加一个完整的文件夹会更容易些:

dependencies {    compile fileTree('libs')}

默认情况下,新创建的Android项目都有一个lib文件夹,并声明用于依赖(dependencies)。代替简单地依赖文件夹中的所有文件,有个过滤器会确保只有JAR文件会被用到:

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

这意味着任何在AS中创建的Android项目,都可以减少lib文件夹中的JAR文件,并且会自动添加到编译路径和最终的APK中。

native库

使用C或C++编写的包可以被编译成特殊平台的本原代码。这些包代表性的包括.so文件。Android plugin默认支持本原库,你只需要在module层创建一个jniLibs目录,并为每一种平台创建子目录。你应该也很擅长把.so文件放到应用目录下。

你的结构看起来如下:

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

如果这种方法无效的话,你也可以在build文件中设置自己的路径:

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

library项目

如果想要分享一个使用Android APIs的或保护Android资源的library,需要创建一个library项目。library项目一般和app项目一样。可以使用相同的task构建和测试library项目,它们也会有不同的构建体。差异在于输出。对于application项目,会生成一个可以安装并运行到Android设备上的APK文件;对于library项目来说,就会生成一个.aar文件。这个文件可被用作Android application项目的library。

创建和使用library项目module

代替使用Android application plugin,脚本语言使用Android library plugin:

apply plugin: 'com.android.library'

有两种添加library项目到应用中的方式。一个是使之成为项目中的module;另外就是创建一个.aar文件,可被重用到多个应用中。

如果在项目中建立library项目作为module,需要把module添加到settings.gradle文件中,并使之作为application module的依赖。settings文件看起来如下:

include ':app', ':library'

这种情况下,library模块称之为library,相当于一个具有相同名称的文件夹。为了在Android module中使用library,需要在Android module中的build.gradle文件中添加一个依赖:

dependencies {    compile project(':library')}

这将在application module的类路径下包含library的输出。

使用.aar文件

如果你创建了想在不同Android应用中重用的library,你可以构建一个.aar文件,并将之添加到项目中作为依赖。当构建这个library时,这个.aar文件将会在该module目录下的build/output/aar目录下生成。为了添加.aar文件作为依赖,需要在application module下创建文件夹,并把.aar文件复制进去,并把这个文件夹作为一个repository:

repositories {    flatDir {        dirs 'aars'    }}

这将使得在该目录下添加任意文件作为依赖成为可能。你可以如下引用依赖:

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

这将告诉gradle查找一个使用.aar扩展的具有确定名称的library。

依赖概念

这里有几个与依赖相关的概念理解起来非常有趣,虽然现在不需要使用它。其中之一就是配置的概念,它揭示了我们本章使用的compile关键词。

配置

有时可能会使用仅存在于特定设备中的SDK,例如源于特定供应商的蓝牙SDK。为了能够编译代码,需要把SDK添加到编译路径中。不过不需要把SDK添加到APK中,因为它已经在这个设备中了。这就是dependency配置的起源了。

gradle把dependencies划到configurations中,后者是以文件集命名。对于一个Android app或library有集中标准的配置:

-compile
-apk
-provided
-testCompile
-androidTestCompile
compile配置是默认的,而且包含了编译主程序需要的全部依赖。这个配置中的任何东西都不仅仅添加到类路径中,也添加到生成的APK里。

apk配置中的依赖将仅被添加到package中,不会添加到编译路径下。provided配置恰好相反,它的依赖不会被打包。这两种配置都只使用JAR依赖。不断的向它们添加library项目将会导致错误。

最后,testCompile和androidTestCompile配置添加用于测试的额外的包。当运行与测试相关的task是会使用到这些配置,这些配置在添加测试框架比如JUnit或Espresso是会非常有用。你只想这些框架在测试APK而非发布APK中出现。

除了这些标准的配置外,Android plugin也会为每一个build变体生成配置,使得它们能够添加依赖到配置当中。如debugCompile、releaseProvided等。这将会非常有用如果你仅添加一个日志框架到测试build中。你可以定义了解更多与此相关的信息在第四章。

语义版本控制

版本控制是依赖管理很重要的一个方面。dependencies被添加到repositories中例如JCenter是被设想遵循一系列规则的版本控制,叫做语义版本控制。使用语义版本控制,版本号总是采用major.minor.patch格式,而且版本号是安装如下规则增加的:

-当作不兼容的API改动时,会做major版本增长
-当在向后兼容管理器中增加功能是会做minor增长
-做修复bug时patch会做增长。

动态版本

一些情况下,每次构建app或library时都想获取最新的依赖版本。实现的最好方式就是使用动态版本。有几种应用动态版本的方式,例子如下:

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总是获取library的最新版本。

要注意小心使用动态版本。如果允许gradle主动选中最新版本,它可能会选择一个不稳定、会导致build中断的最新版本。更糟糕的情况是,使用的build服务器的依赖版本和本机的不同,导致应用行为不一致。

当你在build文件中使用动态版本时,AS会警告你可能出现的问题,如下截图所示:

这里写图片描述

Android Studio中

添加新依赖最容易的方式就是使用AS的Project Structure对话框。从File菜单打开对话框并导向Dependencies标签获得当前依赖的概览:

这里写图片描述

从这个对话框中,可以点击绿色+图标添加依赖,可以添加其他module、文件而且可以搜索JCenter。

使用AS对话框更容易获取项目当前的依赖情况,并增加新的包。不需在build.gradle中手动添加,而且很容易直接从IDE搜索JCenter。

总结

在这一章节中,我们了解了添加依赖到Android项目中的几种方式。学习了repositories、它们的变化形式以及如何不适用repositories依赖文件。

你现在也了解了关于依赖的一些重要的概念,也就是配置、语义版本控制和动态版本。

我们也已经在几种场合提到了build变体,在下一章节,我们将会详细解释build变体到底是什么,以及为什么它们是有用的。build变体使得开发、测试和分发app更容易。理解变体如何工作将会加速开发和分布的进程。

0 0
原创粉丝点击