Gradle For Android(3)--管理依赖关系
介绍
依赖关系管理是Gradle的闪光点。在这个脚本中最好的一点,就是你所需要的只是添加一行到你的build.gradle
中,然后Gradle就会从一个远程仓库中下载与之相关的依赖关系的库,以保证它的Classes对你的Project的是可用的。Gradle甚至解决了依赖项是自己的问题,这种依赖关系被称之为Transitive Dependencies
。
这一章会介绍以来管理并且解释Android Project中添加依赖关系的几种办法。
Repositories
通常我们说的依赖,都是外部依赖,比如说提供给开发者的Libraries。手动管理依赖关系是一个很麻烦的事情,你必须定位Library,然后下载Jar文件,把它Copy到你的Project中,然后reference它。经常这些Jar包在他们的名字上也看不到版本,所以还得在添加的时候记住版本号以便后续升级。你也需要保证Libraries保存在SCV中,用来保证团队成员能够基于该Libraries而不用他们自己手动下载。
使用repositories
可以解决这些问题。一个仓库被认为是很多文件的集合。Gradle不能为Project定义默认的repositories
,所以需要我们手动添加repositories
代码块。如果使用了Android Studio的话,默认就已经完成这个操作了。代码块如下:
repositories {
jcenter()
}
Gradle支持三种不同的仓库:
- Maven
- Ivy
- 静态的文件或者目录
所有的依赖文件都在构建的执行阶段中,从这些仓库中获取。Gradle也会保存一个本地的缓存,所以一个指定的依赖Lib版本只会在机器上下载一次。
每一个依赖都会被三个部分唯一标识,用这三个元素就可以在dependencies代码块中指定依赖的Lib了:
-
group
:指定了该Lib的Organization,通常会是公司域名反过来,例如com.company.department -
name
: 唯一标示该Library -
version
:标识想用的哪个版本号
例如:com.google.code.gson
是Library的group
,gson
是Library的name
,2.3
是Library的version
dependencies {
compile 'com.google.code.gson:gson:2.3'
compile 'com.squareup.retrofit:retrofit:1.9.0'
}
预配置的仓库(Preconfigured repositories)
为了方便,Gradle已经预配置了三个Maven仓库:JCenter
,Maven Central
,Maven Local
。通过下面的代码块即可引入
repositories {
mavenCentral()
jcenter()
mavenLocal()
}
Maven Central和JCenter是两个著名的线上仓库。没必要同时时候,更加推荐使用JCenter,而Android Studio默认就会配置该选项。JCenter是Maven Central的全集。
本地的Maven仓库是一个所有使用过的依赖的本地缓存,我们也可以添加自己的依赖。默认会在Home目录下有一个.m2
的文件夹,在Linux或者Mac上,路径为~/.m2
,而Windows上,路径为%UserProfile%\.m2
。
除了这些预置的仓库外,我们也可以添加公共或者私密的仓库
远程仓库
一些组织创建了一些有趣的Plugin或者Libraries,并且把它们放到了他们自己的Maven或者Ivy服务器上,而没有把它们公开在Maven Center或者JCenter中。为了添加这些依赖,我们所需要做的就是在maven
代码块中添加URL
。
repositories {
maven {
url "http://repo.acmecorp.com/maven2"
}
ivy {
url "http://repo.acmecorp.com/repo"
}
}
如果是私密的仓库,我们可以加入credentials
来访问它。
repositories {
maven {
url "http://repo.acmecorp.com/maven2"
credentials {
username 'username'
password 'secretpassword'
}
} }
最好不要在这个代码块中写入真正的账号密码,最好通过gradle.properties来保存,避免被人看到
本地仓库
在本地硬盘或者网络硬盘上可以构建一个Maven或者Ivy的仓库。通过添加以下配置,我们只需要配置一个URL到一个相对或者绝对路径到硬盘即可:
repositories {
maven {
url "../repo"
}
}
一个新的Android Project会默认依赖Android Support Library。当通过SDK Manager安装Google仓库时,两个Maven仓库就会在本地的硬盘中被创建:
ANDROID_SDK/extras/google/ m2repository
ANDROID_SDK/extras/android/m2repository
这也就是Gradle获取Google Libraries的地方,比如说Android Support Librariy以及Google Play Services等。你可以添加一个常规的目录作为仓库,通过使用flatDirs
,这也可以让你从这个目录下添加文件到依赖关系中:
repositories {
flatDir {
dirs 'aars'
}
}
本地依赖
有时候,我们仍然会手动下载Jar包或者So等方式进行依赖,接下来会介绍如何配置这些文件依赖,Native Libraries以及如何在Project中include library工程
文件依赖
添加Jar文件,我们可以使用Gradle提供的file
和fileTree
方法来添加单个或者整个文件目录作为依赖,或者通过include
来过滤其他的文件:
dependencies {
compile files('libs/domoarigato.jar')
compile fileTree('libs')
compile fileTree(dir: 'libs', include: ['*.jar'])
}
Native Libraries
Android Plugin默认支持Native Libraries,也就是.so文件,只需要我们创建一个目录叫做jniLibs
在Module级别目录下,并且为每个平台创建子目录。把每个so放到对应的目录下。整个结构如下:
app
├── AndroidManifest.xml
└── jniLibs
├── armeabi
│ └── nativelib.so
├── armeabi-v7a
│ └── nativelib.so
├── mips
│ └── nativelib.so
└── x86
└── nativelib.so
如果这种方式不起作用的话,我们可以在Module的build.gradle
中指定它的位置:
android {
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
}
}
Library工程
如果希望创建一个共享的Library的话,和Application工程一样,使用相同的Tasks来构建Library工程,并且同样可以构建多种Library版本。不同的是,Application工程会生成出来一个APK,而Library会生成出来一个AAR文件。这个文件可以作为Project的Library引用。
创建并且使用Library工程
首先,在Module中不使用Android Application Plugin,而是使用Android Library Plugin:
apply plugin: 'com.android.library'
我们有两种方法添加Library工程到Application中:
- 把Library工程作为Module加入Project
- 创建一个AAR文件,可以被多个Application的复用Lib
如果设置Library作为Module加入的话,可以在settings.gradle
加入这个Module,并且把它加入到Application的依赖模块中:
include ':app', ':libraryModule'
在这种情况下,libraryModule
作为Library,并且把它添加到另外一个Module中作为依赖:
dependencies {
compile project(':library')
}
使用AAR文件
如果希望创建一个Library在各个Application中复用,则可以构建出来一个AAR文件,并且作为依赖添加到Project中。AAR文件在assemble
任务执行后,会在build/output/aar/
目录下生成,只要Module构建完成后,也都会生成。
想要添加AAR文件作为依赖,则需要在应用的Module中创建一个目录,然后把aar文件放到该目录中,然后把这个目录作为repository添加到Module中:
repositories {
flatDir {
dirs 'aars'
}
}
上述方式会把文件夹中所有的文件都作为Dependency添加到依赖中,而如果只想添加单独的AAR的话,可以通过下述方式,告诉Gradle,寻找名为libraryname
,扩展名为aar
的文件:
dependencies {
compile(name:'libraryname', ext:'aar')
}
依赖关系的概念--Configuration
JCenter仓库中的Version都会遵从一系列的规则,Version的格式为major.minor.patch
,遵从以下规则:
-
major
版本,当有无法兼容的API版本时,major版本会升级 -
minor
版本,当有向后兼容的功能添加时候,minor版本会升级 -
patch
版本,当修复了一些bug的时候,patch版本会升级
有些时候,可能使用SDK开发我们的功能,比如说蓝牙SDK等,为了能够编译这些代码,我们需要添加SDK到classpath中,但是不需要把SDK包含到APK中,因为这些SDK已经在设备中存在了,这也就是依赖的Configuration中的作用了
Gradle的依赖配置有以下几种:
- compile
- apk
- provided
- testCompile
- androidTestCompile
compile
配置是默认的配置项,并且把所有的依赖项都编译到Applicaion中。每一个配置都不仅仅会添加到classpath中,而是会被添加到APK中。
apk
配置项仅仅会把依赖库添加到包中,而不会把它添加到编译的classpath中。provided
配置项则与之相反,它的依赖项不会被添加到包中,而这两种方式只能够对Jar包的依赖生效,如果使用Library Project的话,会报错。
testCompile
和androidTestCompile
配置项会添加另外特殊的Library作为测试使用。这些配置项只会在执行test相关的任务时,才会使用,比如说使用JUnit或者Espresso的时候,会把相关的Framework添加进去,并且只会在testApk中才会打包这些Framework,而不是在Release Apk中。
除了这些标准的配置项外,Android Plugin也会为每个构建Variant添加一些配置项,比如说debugCompile
,releaseProvided
等等。比如说当只有Debug构建时才要添加Log的Framework时会非常有用。
动态版本
在某些情况下,你可能需要每次都是用最新的依赖库来构建App或者Lib。最好的方法就是是用动态版本,以下为动态版本配置的示例:
dependencies {
compile 'com.android.support:support-v4:22.2.+'
compile 'com.android.support:appcompat-v7:22.2+'
compile 'com.android.support:recyclerview-v7:+'
}
第一行,我们告诉Gradle获取最新的Patch版本。
第二行,我们告诉Gradle获取最新的小版本
第三行,我们告诉Gradle获取最新的版本