参考文章: Gradle与Makefile构建工具的对比
本篇文章是自己学习的梳理。
接触Android studio, 最先“映入眼帘”的自然是Gradle。搜索一下,知道了Gradle是一种“构建工具”。可是,构建工具是什么?Gradle是怎么进行构建工作的?
构建工具
简单地说,构建工具要完成整个项目的如下工作:依赖,编译,测试,发布。参考文章将Gradle与 Makefile的对比,很好让我们理解了构建工具是干什么的。‘“通过一些配置文件和脚本来完成代码的依赖、第三方库的引入、编译的自动化配置等功能”。
Makefile
因为Make也是构建工具,从make的基本功能,可以了解构建工具的具体作用。Make可以说是一种“自动化编译工具”。当项目工程比较大,涉及源码文件,模块比较多,依赖关系复杂时,需要通过 Makefile文件去告诉编译工具怎么去编译,链接。
Makefile的最基础的三个元素: 目标,依赖,命令
目标文件:依赖文件
命令....
即: 目标文件依赖于依赖文件。命令是产生目标文件的规则。如果依赖文件更新,就执行命令去生成新的目标文件。
Make的整个构建工作就是围绕以上的基本规则去完成。
Gradle
Make是主要是针对与c/c++工程的构建工具(不知道这么理解合适不合适)。对于Java工程,有多种构建工具,Gradle是其中一种。在使用Android studio的过程中,很直观地看到它做的工作有:
1. 处理了工程,库等的依赖关系。
2. 处理了工程的一些编译配置问题,甚至可以修改string.xml中的变量,可以在编译过程中修改AndroidManifest.xml。
3. 版本发布相关:签名信息,版本管理
4. 多渠道打包相关
5. 其他
作为工程构建工具,gradle的功能是独立于android studio的。也就是说,我门完全可以使用gradle,在命令行的模式下完成android的基本开发。
全局 build gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
看到。上面对应的gradle版本为: 2.8distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
mavenCentral()
}
dependencies {
// replace with the current version of the Android plugin
classpath 'com.android.tools.build:gradle:1.2.2'
// Since Android's Gradle plugin 0.11, you have to use android-apt >= 1.3
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
}
}
allprojects {
repositories {
mavenCentral()
}
}
classpath 'com.android.tools.build:gradle:1.2.2'
指定该项目的 android gradle plugin的版本。次版本和gradle wrapper中指定的gradle版本有对应关系。两者需要有一定的匹配。
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
指定apt的版本(根据实际情况可选)
Module build gradle
在各个module的根目录下。
在Gradle构造的项目中,项目可以由不同的Module(或者叫做plugin)组成,每个Module都有一个对应的gradle文件(称为 module level build.gradle)。同时还有一个独立于所有module之外的top leavel build.gradle文件。
不同的Module有不同的性质,可以是可执行的android application,也可以是一个jar库文件,这些由build.gradle文件的 apply plugin:语句声明。
apply plugin: 'com.android.application', 声明的是 android application模块
apply plugin: 'java' 声明了一个纯 java library模块,该模块可以被其他模块依赖
apply plugin: 'com.android.library', 也声明了一个可以被其他模块依赖的library模块,但是该模块可以使用android sdk中的api。
......
com.android.application 这个module对应的build.gradle文件分析:以下是我写的demo中的 application project对应的gradle文件内容:
apply plugin: 'com.android.application' // 说明这个module的类型,此处对应的android app的模块
android { // android部分主要是android工程的配置,包括sdk的各种版本设置,manifest设置,编译类型设置等
compileSdkVersion 23
buildToolsVersion "23.0.1"
//以下信息是和AndroidManifest相关的信息,编译时会被插入到AndroidManifest.xml中。
//和我们在Eclipse开发时基本信息一直:报名,目标sdk,版本号等。
defaultConfig {
applicationId "com.hongchang.studiodemo"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
// 编译版本相关
buildTypes {
release {
// 是否进行混淆
minifyEnabled false
// 混淆文件位置
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
// 依赖关系
dependencies {
// 编译libs/ 目录下的jar文件
compile fileTree(dir: 'libs', include: ['*.jar'])
// 单元测试依赖的框架。Gradle会编译并执行 src/test/java 目录下的代码。这里用的是junit的框架
testCompile 'junit:junit:4.12'
// 对jcenter中库的依赖。如果本地不存在,会到jcenter中下载到本地
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.android.support:support-v4:23.1.0'
// 编译LibProject,android project依赖的一个library工程。我的demo中没有这个,我自己加上去用来举例。
compile project('LibProject')
}
settings gradle
在project的根目录下。
需要include本项目的各个module,如下所示,包含两app和libproject两个module:
include ':app', ':libproject'gradle properties
在build.gradle中,就可以使用: buildToolsVersion SDK_BUILDTOOLS_VERSION
定义task和函数
def upload = { -> try { exec { commandLine android.adbExe, 'shell', 'mkdir', dlPath } } catch (ignored) { } exec { commandLine android.adbExe, 'push', project.name + '-debug.apk', dlPath workingDir project.projectDir.toString() + '/build/outputs/apk/' } } task uploadDebug << { upload() }
依赖相关
有时我门依赖了别的project,而这个project已经依赖了重复的某个包,如果我门再次依赖此包,编译时会报 multipledex 异常。例如,我门
重复引用了eventbus的包,需要做如下处理:
provided 'de.greenrobot:eventbus:2.4.0'
遇到“provided dependencies can only be jars”时,极有可能是因为gradle插件的版本需要升级了。