既然要学习Gradle,首先要知道它是什么,它又能干什么,以及怎么使用它。
Gradle是什么?
Gradle 是以Groovy为基础,面向java应用,基于DSL语法的自动化构建工具。
是google引入,替换ant和maven的新工具,其依赖兼容maven和ivy。
Gradle能干什么?
1.更容易重用资源和代码;
2.可以更容易创建不同的版本的程序,多个类型的apk包;
3.更容易配置,扩展;
4.更好的IDE集成;
Android Studio中的android项目通常至少包含两个build.gradle文件,一个是project范围的,另一个是module范围的,由于一个project可以有多个module,所以每个module下都会对应一个build.gradle。
project->build.gradle
project下的build.gradle是整个project的配置,主要配置gradle 版本及 全局依赖仓库、库或者其他全部参数。android studio 现在重要仓库采用jcenter(),之前版本放在mavenCentral。另外有时还没有加入jcenter()仓库的第三方库,也需要在这里配置他们的库地址。需要在这里配置,才能将第三方库拉下来。
apply from: "config.gradle"
buildscript {
repositories {
mavenLocal()
mavenCentral()
jcenter()
maven {
url 'https://jitpack.io'
}
maven {
url 'https://maven.google.com/'
name 'Google'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.sensorsdata.analytics.android:android-gradle-plugin2:1.0.2'
classpath "io.realm:realm-gradle-plugin:4.1.1"
}
}
allprojects {
repositories {
mavenLocal()
mavenCentral()
jcenter()
maven {
url 'https://jitpack.io'
}
maven {
url 'https://maven.google.com/'
name 'Google'
}
}
}
apply from: “config.gradle” :外部配置文件,下面会讲到
buildscript和allprojects中都包含有repositories,是因为他们的作用域不同,buildscript中的仓库是gradle脚本自身需要的资源,而allprojects下的仓库是项目所有模块需要的资源。
config.gradle
ext {
android = [
//编译SDK的版本
compileSdkVersion: 26,
//buildtool 的版本
buildToolsVersion: "26.0.2",
//支持最小android sdk 版本
minSdkVersion : 17,
// 目标版本
targetSdkVersion : 26
//应用版本号
versionCode = 1
//应用版本名称
versionName = "v1.0.0"
]
dependVersion = [
support: "26.0.2"
]
//服务器一 路由地址
serverOneAPIUrl = [
api_url_debug : "\"https://devone.gradle.cn/\"",//开发
api_url_test : "\"https://testone.gradle.cn/\"",//内测
api_url_preview: "\"https://preone.gradle.cn/\"",//预览
api_url_release: "\"https://one.gradle.cn/\""//正式
]
//服务器二 路由地址
serverTwoAPIUrl = [
api_chat_url_debug : "\"https://devtwo.gradle.cn/\"",//开发
api_chat_url_test : "\"https://testtwo.gradle.cn/\"",//内测
api_chat_url_preview: "\"https://pretwo.gradle.cn/\"",//预览
api_chat_url_release: "\"https://two.gradle.cn/\""//正式
]
//服务器三 路由地址
serverThreeUrl = [
api_url_debug : "\"https://devthree.gradle.cn/\"",//开发
api_url_test : "\"https://testthree.gradle.cn/\"",//内测
api_url_preview: "\"https://prethree.gradle.cn/\"",//预览
api_url_release: "\"https://three.gradle.cn/\""//正式
]
dependencies = [
//------------- 分包 ------------
multidex : "com.android.support:multidex:1.0.1",
// ------------- Android -------------
supportV4 : "com.android.support:support-v4:${dependVersion.support}",
appcompatV7 : "com.android.support:appcompat-v7:${dependVersion.support}",
design : "com.android.support:design:${dependVersion.support}",
cardview : "com.android.support:cardview-v7:${dependVersion.support}",
junit : "junit:junit:4.12",
// ------------- reyclerview ------------
recyclerview : "com.android.support:recyclerview-v7:${dependVersion.support}",
// ------------- 网络请求 -------------
retrofit : 'com.squareup.retrofit2:retrofit:2.3.0',
retrofit_rxjava : 'com.squareup.retrofit2:adapter-rxjava2:2.3.0',
retrofit_converter_gson : 'com.squareup.retrofit2:converter-gson:2.3.0',
okhttp_logging_interceptor: 'com.squareup.okhttp3:logging-interceptor:3.8.0',
// ------------- 图片加载 -------------
glide : 'com.github.bumptech.glide:glide:4.3.1',
glideAp : 'com.github.bumptech.glide:compiler:4.3.1',
// ------------- 通信 -------------
eventbus : 'org.greenrobot:eventbus:3.0.0',
// ------------- RxAndroid -------------
rxAndroid : 'io.reactivex.rxjava2:rxandroid:2.0.1',
rxJava : 'io.reactivex.rxjava2:rxjava:2.0.1',
// ------------- json解析 -------------
gson : 'com.google.code.gson:gson:2.8.1',
]
}
项目配置文件,ext全局变量,在每个module的build.gradle文件中都可以随时引用
module->build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
//加载本地配置文件local.properties
Properties properties = new Properties()
InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream();
properties.load(inputStream)
//安卓构建过程需要配置的参数
defaultConfig {
applicationId "com.demo.gradle"
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
multiDexEnabled true
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
}
//ndk配置参数
ndk {
abiFilters "armeabi-v7a", "arm64-v8a", "x86"
}
//java版本号
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
//渠道Flavors_打包
productFlavors {
//可以设置不同渠道渠道号,应用名称
dev { // 开发
buildConfigField "String", "CHANNEL_NUMBER", '"11111"'
}
'360' {
buildConfigField "String", "CHANNEL_NUMBER", '"11112"'
}
GooglePlay {
buildConfigField "String", "CHANNEL_NUMBER", "11113"'
}
//定义apk文件名称格式
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}_${releaseFormatTime()}.apk")
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
//签名
signingConfigs {
release {
keyAlias properties.getProperty('keyAlias')
keyPassword properties.getProperty('keyPassword')
storeFile file(properties.getProperty('storeFile'))
storePassword properties.getProperty('storePassword')
}
}
buildTypes {
debug {
minifyEnabled false
zipAlignEnabled false
shrinkResources false
(..各个服务器的dubug路由地址..)
}
preview {
debuggable false // 是否保留调试信息
minifyEnabled true //是否混淆
zipAlignEnabled true // 包优化
shrinkResources true // 移除不必要的资源
// 签名
signingConfig signingConfigs.release
// 代码混淆规则文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
(..各个服务器的preview路由地址..)
}
release {
//加上后缀
applicationIdSuffix ".release"
minifyEnabled true //是否混淆
zipAlignEnabled true // zip对齐优化
shrinkResources true // 移除不必要的资源
// 不显示Log
buildConfigField "boolean", "LOG_DEBUG", "false"
// 签名
signingConfig signingConfigs.release
//混淆文件的位置
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
(..各个服务器的release路由地址..)
}
}
// 为了解决部分第三方库重复打包了META-INF的问题
packagingOptions {
exclude 'META-INF/ASL2.0'
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
exclude 'META-INF/MANIFEST.MF'
exclude 'sign.properties'
exclude 'keystore.jks'
}
//执行lint检查,有任何的错误或者警告提示,都会终止构建,我们可以将其关掉。
lintOptions {
abortOnError false
}
dataBinding {
enabled = true
}
dexOptions {
//支持最大工程模式
jumboMode = true
javaMaxHeapSize "10g"
//使用增量模式
//incremental false
preDexLibraries = false //预编译
threadCount = "8" //线程数目
}
}
//定义打包时间格式化
def releaseFormatTime() {
return new Date().format("yyyy-MM-dd HH:mm", TimeZone.getDefault())
}
// 发布的日更新包时间尾巴
def releaseFormatDayTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getDefault())
}
// 定义打包时间戳
def releaseTime() {
return new Date().getTime();
}
repositories {
flatDir {
dirs 'aars'
}
maven {
url 'https://maven.google.com/'
name 'Google'
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile rootProject.ext.dependencies.multidex
compile rootProject.ext.dependencies.bugtags
//------------ Android support -----------
//compile rootProject.ext.dependencies.supportV4
compile rootProject.ext.dependencies.design
compile rootProject.ext.dependencies.appcompatV7
compile rootProject.ext.dependencies.cardview
//------------ recyclerview -------------
compile rootProject.ext.dependencies.recyclerview
compile rootProject.ext.dependencies.recyclerview_divider
//------------ 通信 --------------
compile rootProject.ext.dependencies.eventbus
//------------ 网络 ----------
compile project(':api')
//------------ rxAndroid-----------
compile rootProject.ext.dependencies.rxAndroid
compile rootProject.ext.dependencies.topsnackbar
compile rootProject.ext.dependencies.glide
annotationProcessor rootProject.ext.dependencies.glideAp
}
1.buildTypes是指建构的类型,一般只用两种默认类型 debug 和 release,顾名思义 debug 用来配置开发过程中的一些内容;release 用来配置正式发布版本的内容。有时我们需要发布介于debug与release之间的preview 版本。
2.签名信息,可以直接将信息写到gradle.properties或者,然后在然后在build.gradle中引用即可。
3.多渠道的关键在于定义不同的product flavor。这里的flavor名如果是数字开头,必须用引号引起来。
BuildConfig
在build.gradle中配置buildConfigField参数,编译后会在..\app\build\generated\source\buildConfig文件夹下会自动生成对应版本对应module的BuildConfig.java。BuildConfig就会包含对应版本的配置信息。程序中可以直接引用这些数据。例如BuildConfig.DEBUG。
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.demo.gradle";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "wandoujia";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "v1.0.0_debug";
public static final int BUILD_TYPE_INT = 0;
public static final boolean IS_DEBUG = true;
(..各个服务器路由地址..)
}
module 调整目录结构sourceSets
默认情况下,java文件和resource文件分别在src/main/java和src/main/res目录下,在build.gradle文件,andorid{}里面添加下面的代码,便可以将java文件和resource文件放到src/java和src/resources目录下。
sourceSets {
min.java.srcDirs = ['src/java']
min.resources.srcDirs = ['src/resources']
}
Gradle常用命令
./gradlew, ./代表当前目录,gradlew代表 gradle wrapper,意思是gradle的一层包装,大家可以理解为在这个项目本地就封装了gradle,即gradle wrapper, myAPP/gradle/wrapper/gralde-wrapper.properties**文件中声明了它指向的目录和版本。只要下载成功即可用grdlew wrapper的命令代替全局的gradle命令。
理解了gradle wrapper的概念,下面一些常用命令也就容易理解了。
./gradlew 下载更新gradle
./gradlew -v 版本号
./gradlew assemble 构建项目输出
./gradlew check 运行检测和测试任务
./gradlew clean 清除9GAG/app目录下的build文件夹
./gradlew build 运行check和assemble,检查依赖并编译打包
这里注意的是 ./gradlew build 命令把debug、release环境的包都打出来,如果正式发布只需要打Release的包,该怎么办呢,下面介绍一个很有用的命令 assemble<build type=”” name=””>, 如</build>
./gradlew assembleDebug 编译并打Debug包
./gradlew assembleRelease 编译并打Release的包所有渠道的
./gradlew assembleWandoujiaRelease 编译并打包豌豆荚的Release版本
./gradlew assembleWandoujia 编译并打包豌豆荚的所有版本
./gradlew installRelease Release模式打包并安装
./gradlew uninstallRelease 卸载Release模式包