这些是我看Gradle Recipes for Android记录的一些零碎笔记。如有错误或者不当请指正。
在开始之前先了解下什么是工程和子工程,主要是书里提到了这个概念。
假设我们有一个项目叫,HelloWorld
,然后有以下几个Module:app(这个module在建立工程的时候as会自动给我们建立),core,api
那么HelloWorld
就是总工程,那些module就是子工程,他们都有自己的build.gradle
文件。
顶层工程的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:2.1.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
buildscript块告诉gradle去哪里下载插件。默认使用的是Jcenter,你也可以使用mavenCentral(),mavenCentral()是一个maven仓库,默认的是Jcenter。
allprojects块说明顶层工程和所有的子工程都是用Jcenter来下载决定依赖.
Gradle允许自定义Task来插入有向无环图中(DAG),Gradle使用 DAG来解析Task之间的关系(暂时不了解,后文会有)。
type: Delete
表明这个任务是一个可定制的Gradle内置删除任务。在上面的例子,这个任务会从根目录移除所有的构建目录,根目录默认为顶层文件目录。
子工程的Gradle文件
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.1"
defaultConfig {
applicationId "com.yuan.customviewpie"
minSdkVersion 14
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
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:24.1.1'
}
apply
表明使用Android插件,这样才能在下面的android
块中使用领域特定语言(DSL)
.
dependencies
块包括三行:
compile fileTree(dir: 'libs', include: ['*.jar'])
这一行表明,libs文件夹中的所有以.jar结尾的文件都要加入到classpath中。
testCompile 'junit:junit:4.12'
这句表示下载Junit的4.12版本,并且rc/androidTest/java
和src/test/java
中可以写测试用例(但是不可以测试Android API)。
`compile 'com.android.support:appcompat-v7:24.1.1'`这句话表明,让Gradle加入Android的appcompat-v7这个lib,v-7表明兼容到API 7。以为他是被编译的(compile) 所以我们可以在这个工程中使用它。
在顶层构建文件中,它下载了Gradle的Android插件,在子模块中我们通过apply使用了Android插件,只有使用了Android块,我们才可以在子工程build文件中使用android块,我们可以在Android块中,指定compileSdkVersion
和
buildToolsVersion
,这些都最好使用最新的版本,因为最新的版本可以向下兼容并且修复以前的一些Bug。
android
块中的defaultConfig
块定义了一下几种属性。
1.applicationId:应用的包名一般与manifest文件中的的manifest标签的package相同,应用的包名应该与其他应用的包名不相同,一旦上传应用商店就不要更该报名,否则会导致无法升级。
2.minSdkVersion:兼容到的最小的SDK。
3.targetSdkVersion:一般使用最新的SDK版本,否则as会警告。
4.versionCode:应用版本号
5.versionName:应用版本名称
同样的属性配置,Gradle中的配置会1 manfests文件中的配置。
compileOptions
里面的内容表明,应用要使用JDK1.7版本。
Gradle Wapper允许不安装Gradle就执行脚本。Wapper使用更根录下的gradle
文件夹下面的wrapper
下面的gradle-wrapper.jar
和gradle-wrapper.peoperties
来完成这一任务。下面那来看看
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.10-all.zip
distributionUrl
属性表明了去这个地址下载并安装Gradle,第一次晕子那个之后会把Gradle缓存在zipStoreBase
下的zipStorePath
属性下面,以方便所有子任务序列的执行(也就是下载一次就不用下载了,直接去那个文件夹里面拿来用)。
Wapper可以通过执行./gradlew(在Unix系统中)或者使用gradlew.bat(在Windows系统中)来执行,如果Gradle文件名不叫build.gradle那么需要-b来制定一下文件。
gradle如何添加依赖?
有一个叫做dependencies
的块,如下:
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
}
Gradle支持好几种不同的方式来列出依赖,最常用的方式是使用冒号将group,name和version values分隔开,然后使用双引号包起来,例如:
compile 'com.android.support:appcompat-v7:23.3.0'
com.android.support就是group.
appcompat-v7是name.
23.3.0是version values.
他们之间使用:
分隔开.
每个依赖都和一个配置相关联(例如:'com.android.support:appcompat-v7:23.3.0'
这个依赖和compile
这个配置相关联),Android工程包含compile
, runtime
, testCompile
,和testRuntime
这几种配置.插件可以增加额外的配置,你也可以定义你自己的。
以依赖的语法:
compile group:"com.android.support",name:"appcompat-v7",version:"24.1.1"
这种写法和compile 'com.android.support:appcompat-v7:23.3.0'
写法是相同的。
还可以这样写com.android.support:appcompat-v7:23.+
,这个+
号代表使用23.0或者23.0以上的lib。(一般不推荐折磨用,不给定明确的版本,出了Bag不好调)。
如果你不想从仓库直接获取lib,而是自己添加jar,那么可以使用files
或者fileTree
语法,例如:
dependencies {
//添加libs下面的a.jar和b.jar
compile files('libs/a.jar', 'libs/b.jar')
//添加libs目录下面的以.jar为结尾的文件
compile fileTree(dir: 'libs', include: '*.jar')
}
Gradle会自动管理间接依赖,什么是间接依赖呢?比如说Retrofit依赖了OkHttp,而我们的应用依赖Retrofit,那么我们在build.gradle中只需要配置Retrofit依赖那么他就会自动下载Retrofit和OkHttp。
我们也可以 使用transitive
来开启或者关闭这个功能。例如
dependencies {
runtime group: 'com.squareup.retrofit2', name: 'retrofit', version: '2.0.1',
transitive: false
}
也可以这样:
dependencies {
//可以这样
compile 'com.squareup.retrofit2:retrofit:2.1.0@jar'
//也可以这样
compile group: 'com.squareup.retrofit2', name: 'retrofit2',
version: '2.1.0', ext: 'jar'
}
不过个人认为一般还是允许下载间接依赖的,这样我们可以省下很多事。
repositories
用来指定现在jar包的远程仓库。
Android Studio默认使用的是jcenter
repositories {
jcenter()
}
也可以自己指定为maven
repositories {
//maven的北地仓库,如果本地有,那么就直接使用本地的,如果没有就去远程下载.
mavenLocal()
//maven远程仓储,本地找不到就去这里下载
mavenCentral()
}
还可以通过Url指定Maven仓库,如下
repositories {
maven {
url 'http://repo.spring.io/milestone'
}
}
有的maven仓库需要认证,可以这样写
repositories {
maven {
credentials {
username 'username'
password 'password'
}
url 'http://repo.mycompany.com/maven2'
}
}
使用lvy仓库(lvy 也是依赖管理工具)
repositories {
ivy {
url 'http://my.ivy.repo'
}
}
也可以使用本地目录作为仓库:
repositories {
flatDir {
//jar包在lib文件夹
dirs 'lib'
}
}
如果同时使用多个仓库,那么Gradle会从到下进行搜索,如果找到了就停止,否则会查找下面的仓库。
例如:
repositories {
jcenter()
mavenCenter()
}
gradle会先查找jcenter如果全都找到了就不会再去mavenCenter找,如果有没找到的那么就继续去mavenCenter中找。