内容来源
虽然内容为转载,但是自己也是经过详细学习和为文章重构的,^ ^
导读
Gradle基于Groovy的特定领域语言(DSL)编写的一种自动化建构工具,Groovy作为一种高级语言由Java代码实现,本文将对Gradle一些常见问题进行一一介绍:
- 理解 Gradle 与 android app 之间的关系,以及 Gradle 需要构建的 build 文件。
- 在 Android Studio 中执行 Gradl e命令。
- 在 Android app 添加 java 库文件。
- 将 eclipse 工程导入 Eclipse ADT 工程
- 如何为一个 APK 文件进行数字签名
1. Android Gradle基础
android 应用程序使用开源工具 Gradle 构建。Gradle 一种艺术 API,非常容易的支持定制,并且在 java 世界有着广泛的应用。`Android 为了实现编译、打包等,开发者开发了 Android插件为 Gradle 添加了一系列的新特征`,特别是在构建 Android app 上的应用,包括:构建类型、多样化、签名配置、库文件工程等等功能。
1.1 Android Gradle 构建文件
在我们使用 Android Studio工具开发 Android 应用的时候,当创建一个新的 Android 工程,默认的 Gradle 构建文件包括了setting.gradle
,build.gradle
和app/build.gradle
。具体位置如图所示。
setting.gradle
include ':app'
build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0+'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
其实原始的 Gradle 默认情况下并不包含 Android 功能。Google 为 Gradle 提供了Android 插件,允许用户很容易的配置 android 工程编译脚本。编译脚本 (buildscript) 在编译工程的根目录,构建文件 (build.gradle) 用来告知 Gradle 去哪里下载对应的插件。
从上面列出的代码中我们可以看到插件的默认下载是从 jcenter
中,意味着 jcenter
就是当前的目标库。* 虽然 jcenter 仓库是当前默认的,但是其它的仓库也是支持的
*,尤其是 mavenCenteral() 作为 maven 的远端默认仓库。JCenter 仓库的所有内容通过一个 CDN 经由 HTTPS 连接传输,速度也是很快的。
上面代码中的 allprojects
部分表示当前的根目录工程和所属的子工程
默认情况下都使用 jcenter() 远端仓库用来支持java库的依赖。
Gradle 允许用户定义很多任务(tasks),并插入到有向无环图(directed acyclic graph,DAG)中,Gradle 通过 DAG 来解析任务之间的依赖关系。在上面代码中一个 clean 任务
已经添加到根目录的构建文件中。其中的 type: Delete
表示依赖 Gradle 中定制已有的 Delete任务。在这种情况下,该任务会移除在工程根目录下的构建目录(也就是 build 目录)。
app 作为项目工程的 module (模块),内部需要包含 build.gradle 来支持 module 编译,接下来来看一下 app 目录下的 build.gradle。
app/build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.kousenit.myandroidapp"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
}
这部分的代码功能并非由 Gradle 工具提供,是由 Android 插件构建系统提供
,通过加入 android 标签
,允许 android 块使用 DSL (Domin Specific Language) 编写配置。
dependencies 部分包含了三行。
- 第一行使用
fileTree做依赖
,表示所有在libs目录下的以.jar为后缀名的文件添加到编译路径中。 - 第二行告诉 Gradle 去下载版本为4.12的 JUnit 并为其添加命名 testCompile 。依赖着 JUni t类将在 src/androidTest/java
路径下生效,用来增加测试单元(本文没有介绍测试)。 - 第三行告诉 Gradle 添加 appcompat-v7,版本为 23.3.0,从 JCenter 支持库中获取。
1.2 默认配置
app/build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.kousenit.myandroidapp"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
在 build.gradle 文件的顶部添加 Android 应用程序插件。Module (模块) 编译文件通过 apply plugin: 'com.android.application'
,加载应用程序插件,从而使 Gradle DSL 支持 android 标签。
android DSL 使用模块方式嵌入。必须指出编译目标版本(compileSdkVersion)和编译工具版本(buildToolsVersion)。两个值尽量跟进较近的版本,而非老版本,因为新版本会修复老版本工具含的一些bug 。
属性 | 解释 |
---|---|
applicationId | 应用的包名,该值必须唯一 |
minSdkVersion | 应用支持的最小Android SDk版本 |
targetSdkVersion | 应用目标版本,Android studio会根据当前版本提示相应的警告信息 |
versionCode | 用一个整数表示当前app的版本,用以升级使用 |
versionName | 用一个字符表示当前app版本名称,用以升级使用 |
转到 Gradle 之后,minSdkVersion 和 buildToolsVersio n属性被指定,这两个属性和 Android Manifest 中的
1.3 使用命令行执行Gradle脚本
从命令行需要用户提供 Gradle wrapper 或者安装 Gradle 并直接运行。
gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
其中 distributionUrl
属性表示 wrapper 包将要下载和安装gradle-2.14.1
版本。在第一次执行结束之后,Gradle 目标将被缓存在 zipStorePath
文件夹,在 zipStoreBase 目录之下,以后每次构建将直接使用缓存的版本构建任务。
命令非常简单:
./gradlew build
最后输出的apk在app/build/outputs/apk目录下。我们也可以执行多任务通过空格:
** ./gradlew lint assembleDebug**
其中查看依赖树通过:
** ./gradlew anDep**
** 取消编译任务: ./gradlew pro**
如果不想使用编译build.gradle文件,使用-b切换编译脚本文件:
./gradlew -b app.gradle
1.4 在android Studio上执行编译脚本
如何在 Android Studio 环境下,执行编译任务?当我们创建 Android 工程后,Android Studio 会为多个工程脚本生成 Gradle 构建文件。IDE提供了Gradle任务列表的可视化视图,如下图所示:
Gradle提供了很多分类,像 android, build, install 和 other。执行某一个任务的时候只需要双击具体的名称,在 Gradle 窗口中。每次运行一个特殊的 task,运行配置就会被创建并存储在 Run Configurations 菜单下,所以再次运行的时候可以在这里选择。
Android studio 提供了 Gradle Console 输出相应的编译信息
1.5 为项目工程增加依赖库
默认情况下,Android 应用包含了两个 gradle 文件:一个在根目录下,一个在应用目录下。在应用目录下的 gradle 脚本需要增加依赖:
app/build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
}
每一个依赖关系表示了一个配置。
Android 工程的依赖包含了编译、运行、测试编译、测试运行。完整的依赖包含三个部分:group
,name
, 和 version
信息。插件可以增加额外的配置信息,也能够定义自己的信息。完整的信息如下:
testCompile group: 'junit', name: 'junit', version: '4.12'
简写为:
testCompile 'junit:junit:4.12'
版本简写:
testCompile 'junit:junit:4.+'
如果你想配置相应的文件
,可通过 files
和fileTree
增加依赖:
dependencies {
compile files('libs/a.jar', 'libs/b.jar')
compile fileTree(dir: 'libs', include: '*.jar')
}
传递依赖:
./gradlew androidDependencies
Gradle默认情况下是开始网络检查依赖库的,如果有特殊需求需要关闭,采用transitive标志关闭网络请求:
dependencies {
runtime group: 'com.squareup.retrofit2', name: 'retrofit', version: '2.0.1',
transitive: false
}
将transitive标志改成false会阻止依赖的下载。所以如果需要的话必须加载自己的本地。如果希望模块是jar文件,写法如下:
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.4[@jar](https://my.oschina.net/u/1767170)'
compile group: 'org.codehaus.groovy', name: 'groovy-all',version: '2.4.4', ext: 'jar'
}
1.6 为 android studio 增加依赖库
有经验的开发者可以很轻松的编辑 build.gradle 文件,而不需要借助 IDE 的帮助。但是 IDE 也给出了相应的编辑视图。
打开File->Project Structure,选择相应的 module s即可对 build.gradle 进行编辑。如下图所示:
- 选择 Porperties 选项卡,可以查看 Compile SDK Version 和 Build Tools Version等信息。
-
选择 Dependencies 选项卡,可以查看依赖的库、工程等信息。
其中Dependencies选项卡中的Scope行允许用户配置依赖库是提供到apk中,还是只是编译的时候依赖:
- Compile
- Provided
- APK
- Test compile
- Debug compile
- Release compile
1.7 配置仓库
在 Gradle 的 dependencies 是怎么样精准的找到相应的依赖的呢?通过在 repositories 配置的,所有的 dependencies 都会去找到相应的依赖,才可以正常编译。默认仓库为 JCenter。注意当前使用 HTTPS 连接。
repositories {
mavenLocal()
mavenCentral()
}
一些Maven库也可以通过URL添加,如下例添加一个maven库:
repositories {
maven {
url 'http://repo.spring.io/milestone'
}
}
** 密码保护仓库 (需要进一步了解)**可以使用 credentials 模块来表示,通过用户名和密码的校验来获取依赖仓库,代码如下所示:
repositories {
maven {
credentials {
username 'username'
password 'password'
}
url 'http://repo.mycompany.com/maven2'
}
}```
也可以将用户名和密码值移到 gradle.properties 文件中。Ivy 和 local 仓库语法类似,参考下例:
repositories {
ivy {
url 'http://my.ivy.repo'
}
}
当使用本地文件,可以通过flatDir语法来创建仓库,。如下例所示:
repositories {
flatDir {
dirs 'libs'
}
}```
使用 flatDir 是使用 files 或是 fileTree 方案的一种替代,fileTree 需要指定路径,就不再需要指定 flatDir 本地文件,但是 aar 文件依赖的时候需要指定本地库,使用 latDir 标签。当我们为应用程序构建添加很多仓库。Gradle 轮询每一个仓库,直到解析完毕所有的依赖,找到所有依赖,否则会报出错误 。