[转载]深入理解 Gradle 编译一 Android 基础篇

内容来源

虽然内容为转载,但是自己也是经过详细学习和为文章重构的,^ ^

导读

 Gradle基于Groovy的特定领域语言(DSL)编写的一种自动化建构工具,Groovy作为一种高级语言由Java代码实现,本文将对Gradle一些常见问题进行一一介绍:
  1. 理解 Gradle 与 android app 之间的关系,以及 Gradle 需要构建的 build 文件。
  2. 在 Android Studio 中执行 Gradl e命令。
  3. 在 Android app 添加 java 库文件。
  4. 将 eclipse 工程导入 Eclipse ADT 工程
  5. 如何为一个 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.gradleapp/build.gradle。具体位置如图所示。

[转载]深入理解 Gradle 编译一 Android 基础篇_第1张图片
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 中的 标签属性内容一致。Android Manifest 中的 标签已经被取消,如若值仍然存在在 Manifest 中,值将被 Gradle 中的值覆盖。

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 基础篇_第2张图片

Gradle提供了很多分类,像 android, build, install 和 other。执行某一个任务的时候只需要双击具体的名称,在 Gradle 窗口中。每次运行一个特殊的 task,运行配置就会被创建并存储在 Run Configurations 菜单下,所以再次运行的时候可以在这里选择。


[转载]深入理解 Gradle 编译一 Android 基础篇_第3张图片

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.+'

如果你想配置相应的文件,可通过 filesfileTree增加依赖:

dependencies {
    compile files('libs/a.jar', 'libs/b.jar')
    compile fileTree(dir: 'libs', include: '*.jar')
}
[转载]深入理解 Gradle 编译一 Android 基础篇_第4张图片

传递依赖:

./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 进行编辑。如下图所示:


[转载]深入理解 Gradle 编译一 Android 基础篇_第5张图片
  • 选择 Porperties 选项卡,可以查看 Compile SDK Version 和 Build Tools Version等信息。
  • 选择 Dependencies 选项卡,可以查看依赖的库、工程等信息。


    [转载]深入理解 Gradle 编译一 Android 基础篇_第6张图片

其中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 轮询每一个仓库,直到解析完毕所有的依赖,找到所有依赖,否则会报出错误 。

你可能感兴趣的:([转载]深入理解 Gradle 编译一 Android 基础篇)