文章目录
此文使用的IDE是Android Studio
1. Gradle
Gradle是基于Groovy语法,而Groovy又是基于Java。所以四舍五入一下Gradle就是基于Java的。
在Gradle中,每一个待编译的工程都是一个Project。每一个Project在构建的时候都包含一系列的Task。比如一个Android APK的编译可能包含:Java源码编译Task、资源编译Task、JNI编译Task、lint检查Task、打包生成APK的Task、签名Task等。
一个Project到底包含多少个Task,其实是由编译脚本指定的插件决定。插件是什么呢?插件就是用来定义Task,并具体执行这些Task的东西。
那么,插件到底是怎么加载的呢,打开任意一个Android工程,module:app的build.gradle,最上面有一行
apply plugin: 'com.android.application'
或者(不同版本的gradle写法不同,但是都是那个意思,意会即可)
plugins{
id ‘com.android.application'
}
这就表示该module应用了Android的插件,其中就会包括了一大堆只有Android才有的配置,比如android的闭包,如果你是新建一个Java Library,那么在它的build.gradle中,一定不会有android闭包。
1.1 项目结构
假设现在有一个Android工程的文件夹
myapp
├───build.gradle
├───settings.gradle
├───app
├───build.gradle
├───src
├───module_a
├───build.gradle
├───src
├───module_b
├───build.gradle
├───src
其中app,module_a,module_b都是Android Library,那么在这个工程中,一共有三个project,每个module都是一个独立的project,所以它们的根目录下都必须要有一个build.gradle以用于它们构建。
但是,多个project分别编译起来非常麻烦,更不用说我们平时工作时,不同的project还有相互的依赖关系,所以Gradle会把它们合起来一起编译了(这也就是为什么我们项目有多个module时,只要其中一个报错就无法运行的原因,因为Gradle总是将他们一起编译)。
在我们的Android工程下,有一个build.gradle和settings.gradle。
-
build.gradle:这个文件一般配置一些全局属性,加在这里的内容相当于加在每个module的build.gradle的内容。
-
settings.gradle:表明这个工程有多少个子工程(也就是子project,于是父工程也是project,以后子工程都用module来称呼)。看一眼该文件的内容就知道是什么意思了。
include ':app', ':module_a', ':module_b' 或者(不同版本的gradle写法不同,但是都是那个意思,意会即可) include ':app' include ':module_a' include ':module_b' rootProject.name = "myapp"
2. build.gradle
说完了项目结构后,来看一下build.gradle这个文件的具体内容,哪些代码代表了什么意思。
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.1"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
allprojects:顾名思义,在这里配置的参数,会同等的配置到所有module的build.gradle中。
2.1 repositories
它表明远程的代码仓库地址,代表着我们远程依赖包的来源。这么说可能有点绕口,那我举个例子。
例:假设你的Android项目要依赖一个网络上的包,就假设你要引用一个别人在github上封装的Recyclerview插件吧。那么这个依赖包应该到哪里去下载,百度?QQ?360?谷歌?我们需要告诉项目依赖包的具体来源网站,这个就是repositories的意义了。
-
maven{}:添加某个代码仓库的地址,用maven闭包和url。可以加网络仓库,也可以加本地仓库(也就是你电脑上的代码仓库)
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
-
google():其实就是 maven { url ‘https://dl.google.com/dl/android/maven2/’ },只是因为Android每个项目都一定会用到这个,所以就简写了,它是谷歌的内置库,我们的com.android.tools.build:gradle就是从这里来的。
-
jcenter():其实就是 maven{ url ‘https://jcenter.bintray.com’ },只是因为Android每个项目大概率都会用到,所以就简写了。一般我们的开源库都是从这个网站下的,而我们自己写的开源库一般也会上传到这里(或者Jitpack)。怎么上传看这里
-
mavenCentral():其实就是 maven { url ‘https://repo1.maven.org/maven2’ },已经被jcenter取代。
在几年前(现在可能也有),我们由于上外网的网速较慢等各种原因,经常无法正常下载jcenter或者google的库,这个时候就会用到国内的aliyun镜像。
buildscript {
repositories {
jcenter { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
}
}
2.2 dependencies
指定当前项目的所有依赖关系,这个不用多说。你的项目需要哪些功能,就上网去依赖哪些项目即可。当然这个依赖不仅限于网络,本地也可。
- implementation:添加某个项目的依赖,可以添加网络依赖和本地依赖
- api:添加某个项目的依赖和这个项目本身所包含的依赖。和implementation的区别看这里
- compile:已弃用,现在都用api。
- classpath:Classpath设置的目的,在于告诉IDE,在哪些目录下可以找到您所要执行的Java程序所需要的类或者包。
用最直白的话来说,不包括buildscript,我们的项目中dependencies中所有添加的代码库,都会一起加入到我们的项目中来,添加的越多,代码就越多,app就越大。所以Android studio一般不推荐我们使用api而是使用implementation,api会连带更多代码进来。
2.3 buildscript
构建项目时相关的配置,其中也包括一个repositories和dependencies。
我这么说吧,我们项目的代码,在编译之后,会变成app。那么到底是谁来执行编译的这个过程呢?项目不可能无缘无故的自己就变成可执行程序。也就是说,会有一段代码,让我们的项目编译成app。而这段代码就在buildscript中配置。
Note的内容写的是:buildscript中dependencies添加的库只做编译用,不会添加到项目工程中。
对buildscript的工作过程做一个大白话解释:
-
我们需要将项目的代码编译成可以运行的app
-
而com.android.tools.build:gradle这个包可以完成编译这个功能(怎么编译的先别管),所以我们在dependencies中添加了它。
dependencies{ classpath "com.android.tools.build:gradle:4.1.1" }
-
那么这个包去网络上的哪里可以下载到呢?我们在repositories中添加了google(),告诉了IDE(一般指Android Studio)去谷歌的网站上可以下载到这个包。
repositories { google() }
-
于是项目去谷歌网站上下载了这个包后,用这个包对我们的项目进行编译,让项目变成了一个可以运行的app。
3. module的build.gradle
3.1 plugins
声明某个插件的类型并将这个插件应用与该module中。
每当我们apply plugin 'com.‘com.android.application’ 时,就表示,在改module中引用android application插件,这样该module就会按照android application的方式进行编译。
插件总是会从我们在buildscript中classpath内添加的包中去查找。如果找不到,就会报错。
3.2 android
只有应用了com.android.library或者com.android.application才会有的闭包,java-library会因为找不到android这个方法而无法编译,内部就是一些Android项目用的参数
参考材料
Gradle入门学习—认识buildeTypes和dependencies - 文酱 - 博客园
https://www.cnblogs.com/wenjiang/p/6638927.html
Gradle for Android 第一篇( 从 Gradle 和 AS 开始 )_neu - SegmentFault 思否
https://segmentfault.com/a/1190000004229002
Gradle入门学习—认识buildeTypes和dependencies - 文酱 - 博客园
https://www.cnblogs.com/wenjiang/p/6638927.html
深入理解Android之Gradle_Innost的专栏-CSDN博客_android gradle
https://blog.csdn.net/innost/article/details/48228651
jcenter()和mavenCentral()_yh18668197127的博客-CSDN博客
https://blog.csdn.net/yh18668197127/article/details/85089557