前言

Android应用程序使用开源的Gradle构建系统来构建。Gradle是在Java世界中广泛使用的、易定制化的现代化API。Android的Gradle插件针对Android应用程序添加了大量的特性,包括构建类型(build type)、定制(product flavor)、签名管理(signing configuration)、库项目(library project)等。

学习资料

  • Gladle用户指南
  • Android Studio 构建指南
  • Android Studio Gradle,插件使用指南
  • Gradle DSL语言API
  • 跟我学Gradle「中文版」

参数说明

Setting.gradle

include ':app'

include语句表示app子目录是唯一的子项目。如果你添加一个Android库项目,其也会被添加到这个文件。

build.gradle

你可以在构件文件顶层添加所有子项目或模块通用的配置选项。

buildscript {    repositories {        jcenter()        maven { url 'https://dl.google.com/dl/android/maven2/' }    }    dependencies {        classpath 'com.android.tools.build:gradle:3.0.1'        // 注意:不要把你的应用程序依赖放在这里;它们属于各独立模块的build.gradle文件。    }}allprojects {    repositories {        jcenter()    }}task clean(type: Delete) {    delete rootProject.buildDir}

Gradle的安装本身默认不包含Android的功能。Google为Gradle提供了一个Android的插件,其简化了Android项目的配置。构建文件顶层的buildscript块告诉Gradle去哪下载这个插件。
  正如你看到的,默认这个插件会从jcenter下载,即Bintray JCenter Artifactory库。也支持其他的库(特别是mavenCentral(),默认的Maven仓库),但是JCenter现在已经成默认的了。JCenter中的内容都使用HTTPS连接并通过CDN来提供,同时也更快速。
  allprojects段顶层项目和所有子项目都默认使用jcentrer()仓库来下载所有的Java第三方依赖库。
  Gradle允许你自定义你自己的task,并插入到有向无环图(Directed Acyclic Graph,DAG),Gradle用其解析task之间的关系。这里一个clean task被添加到了构建的顶端。type: Delete表示这个新的task是Gradle内置的Delete task的一个自定义实例。在这个例子中,这个task将构建目录从根项目中删除,默认构建目录即顶层中的build。

build.gradle[app]

apply plugin: 'com.android.application'android {    // 前两个都应该被赋予最新可用的版本,因为他们都是向后兼容的,并且包含了所有当前的漏洞修复。    compileSdkVersion 27 // 目标编译环境    buildToolsVersion '26.0.2' // 构建工具的版本    defaultConfig {        // 应用程序的“package”名字,在Google Play中应该是唯一的。        // 这个值在你的应用程序的整个生命周期都不能被改变。        // 改变这个值会使你的应用程序被认为是一个全新的应用程序,也就没法更新。        // 这个值是Android Manifest根元素下的一个package的属性。        applicationId "link_work.elderlycommunity"        // 应用程序支持的最小版本        minSdkVersion 19        // 应用程序目标的Android版本。如果该值没有被设置为最新版本,        // Android Studio会发出警告。        targetSdkVersion 27        // 版本号        versionCode 1        // 字符串,发行版本        versionName "1.0"        flavorDimensions "versionCode"        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"    }    // 表示app期望使用的SDK版本    compileOptions {        sourceCompatibility JavaVersion.VERSION_1_8        targetCompatibility JavaVersion.VERSION_1_8    }    // APP签名,密钥创建过程请看下文。    signingConfigs {        config {            // 用户名            keyAlias 'androiddebugkey'            // 密码            keyPassword 'android'            // 秘钥保存地址            storeFile file('./debug.jks')            // 存储密码            storePassword 'android'        }    }    // 编译类型,详情请看下文。    buildTypes {        debug {            minifyEnabled false            useProguard false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'            testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguardTest-rules.pro'            signingConfig signingConfigs.config // 调用签名        }        release {            minifyEnabled true            useProguard true            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'            testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguardTest-rules.pro'        }    }}dependencies {    // 依赖库}

targetSdkVersion

目标版本的设定值告知Android,应用是为哪一个API级别设计的。大多数情况下,目标版本就是最新发布的Android版本。

什么时候修改目标SDK版本?新发布的SDK版本会改变应用在设备上的显示方式,甚至连操作系统后台运行行为都会受到影响。如果应用开发完成,应确认它在新版本上能否如期那样运行。

降低SDK目标版本可以保证的是,即便在高于目标版本的设备上,应用仍然可以正常运行,且运行行为仍和目标版本一致。这是因为新发布版本中的变化已被忽略。

签名

查看签名

进入.android文件夹,可以查看当前已经创建的keystore
  使用keytool -list -keystore debug.keystore可以查看keystore的内容。

生成签名文件

生成指令为:keytool -genkey -v -keystore myApp.keystore -alias China -keyalg RSA -keysize 2048 -validity 10000
  创建一个用RSA算法加密,大小为2KB,使用SHA256进行签名,10000天的有效期的密钥。

// APP签名signingConfigs {config {// 用户名keyAlias 'androiddebugkey'// 在签发过程中使用一个特定密钥的密码keyPassword 'android'// 秘钥保存地址storeFile file('./debug.jks')// 密钥库文件自身使用的密码storePassword 'android'}}

编译类型

// 编译类型buildTypes {debug {minifyEnabled falseuseProguard falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguardTest-rules.pro'            signingConfig signingConfigs.config // 调用签名        }        release {        minifyEnabled true        useProguard true        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguardTest-rules.pro'        }    }}
参数 说明
minifyEnabled 代表在打包的时候app包自动删除无用的资源。如果设置为true,Gradle还会删除无须用到的依赖库。这只会在shrinkResource属性同时设置为true的时候才会生效。
shrinkResource 见上。
useProguard 开启混淆。
proguardFiles 混淆文件规则。

资源分包

你也许遇到过一种情况,当你的APP写到一定程度的时候,你的layout文件和drawable文件会非常的多,这个时候,你可能就想要对资源文件进行分包。

首先,我们可以在app.gradle增加如下内容:

android {    sourceSets {        main {            // 配置res文件夹            res.srcDirs = [                    'src/main/res/layout/activity',                    'src/main/res/layout/fragment',                    'src/main/res/layout/ui',                    'src/main/res/layout',                    'src/main/res/drawable/img',                    'src/main/res/drawable/xml',                    'src/main/res/drawable',                    'src/main/res'            ]        }    }}

需要注意的是,目录的顺序需要从最里到最外(即父文件夹放在最后)。

分包结果如下:

说明

./gradlew是在Gradle工程下,如果本地配置了gradle环境,可以使用gradle。一般建议使用Gradle工程目录下的./gradlew,防止版本问题。

参数 说明
-i Gradle默认不会输出很多信息,你可以使用-i选项改变日志级别为INFO
-s 如果运行时错误发生打印堆栈信息
-q 只打印错误信息
-?-h,–help 打印所有的命令行选项
-b,–build-file Gradle默认执行build.gradle脚本,如果想执行其他脚本可以使用这个命
令,比如gradle -b test.gradle
–offline 在离线模式运行build,Gradle只检查本地缓存中的依赖
-D,–system-prop Gradle作为JVM进程运行,你可以提供一个系统属性比如:-Dmyprop=myValue
-P,–project-prop 项目属性可以作为你构建脚本的一个变量,你可以传递一个属性值给build脚本,比如:-Pmyprop=myValue
task 显示项目中所有可运行的任务
properties 打印项目中所有可配置的属性值

显示任务

检查构建脚本,并显示所有的任务:./gradlew -q task

任务名称缩写

Gradle支持命令行输入任务名的驼峰简写:

task groupTherapy << {    ...}task generateTests << {    ...}

这个时候输入./gradlew gT会报错,因为存在两个简写一致的情况。

排除一个任务

参数-x用于排除一个任务:./gradlew groupTherapy -x yayGradle0

构建项目

开始构建项目:./gradlew build

命令

包装器

Gradle包装器,包装器是Gradle的一个核心特性,它允许你的机器不需要安装运行时就能运行Gradle脚本,而且她还能确保build脚本运行在指定版本的Gradle。它会从中央仓库中自动下载Gradle运行时,解压到你的文件系统,然后用来build。终极目标就是创建可靠的、可复用的、与操作系统、系统配置或Gradle版本无关的构建。

task wrapper(type: Wrapper) {    gradleVersion = '1.7'}

然后执行这个任务:gradle wrapper

记住你只需要运行gradle wrapper一次,以后你就能用wrapper来执行你的任务,下载下来的wrapper文件会被添加到版本控制系统中。如果你的系统中已经安装了Gradle运行时,你就不需要再添加一个gradle wrapper任务,你可以直接运行gradle wrapper任务,这个任务会使用你的Gradle当前版本来生成包装文件。

项目

Project实例允许你访问你项目所有的Gradle特性,比如任务的创建和依赖了管理,记住一点当访问你项目的属性和方法时你并不需要显式的使用project变量–Gradle假定你的意思是Project实例,比如setDescription("myProject")

外部属性

外部属性一般存储在键值对中,要添加一个属性,你需要使用ext命名空间。

project.ext.myProp = 'myValue'ext {    someOtherProp = 123}

相似的,外部属性可以定义在一个属性文件gradle.properties中:

exampleProp = myValuesomeOtherProp = 455

我们可以在项目中直接访问这两个变量:

assert project.exampleProp == 'myValue'task printGradleProperty << {    println "Second property: $someOtherProp"}

任务

动作就是你在任务里面放置构建逻辑的地方,Task接口中提供了两个方法来声明任务的动作:doFirstdoLast,当任务执行的时候,定义在闭包里面的动作逻辑就按照顺序执行。

version = '0.1-SNAPSHOT'task printVersion {    doFirst {        println "Version: $version"    }    doLast {        println "Version: $version"    }}

Gradle的生命周期

  • 初始化
  • 配置
  • 执行

Android Studio使用

下面放上一些比较常见的Android Studio的Gradle使用方式。

多线程编译

在项目根目录中创建gradle.properties,加入以下配置

org.gradle.daemon=trueorg.gradle.parallel=true

解决依赖问题和编译

  • 打印依赖树:gradle dependencies
  • 编译:gradle build
  • 编译查看详细信息:gradle build --stacktrace

Manifest merger failed with multiple errors

通过以下命令,可以找出问题所在:

  • Mac and Linux:./gradlew processReleaseManifest --stacktrace
  • Windows:gradlew processReleaseManifest --stacktrace

附录

  • Gradle Build Language Reference
  • Declaring Dependencies
  • Managing Dependency Configurations

书籍

  • Gradle Recipes for Android
    • [美国]Ken Kousen
  • 《Android编程权威指南》

更多相关文章

  1. 在Android中使用Lua脚本 —— Programing Lua on Android
  2. android 游戏导引(1. 建立 OpenGL 项目)
  3. 【整理】android开源项目【tool篇】
  4. Eclipse ADT 创建Android项目----工程目录详解
  5. 高手速成android开源项目【tool篇】
  6. [Android]调试webview
  7. 【android】AsyncTask完全剖析(二)
  8. Android百度地图——定位SDK(版本v3.1)(一)
  9. 安卓系统框架介绍

随机推荐

  1. Android(安卓)获取目录下所有文件、获取
  2. Android(安卓)Studio 2.0 正式版发布啦 (
  3. Android(安卓)Bug记:'Canvas:trying to us
  4. Android特殊字符
  5. android 学习使用Activity转场动画及shar
  6. 工作环境搭建(9) - CentOS7命令行安装And
  7. adb Not running as root. Try "adb root
  8. android 获取手机所有短信内容
  9. android scaleType的属性
  10. android里发送mail的几种方式