Gradle简介
Gradle是一个自动化构建工具,采用Groovy的Domain Specific Language(领域特定语言)来描述和控制构建逻辑。具有语法简洁、可读性强、配置灵活等特点。基于Intellij IDEA社区版本开发的Android Studio天生支持Gradle构建程序。Groovy是一种基于JVM的敏捷开发语言,结合了Phthon、Ruby和Smalltalk的许多强大特性。同时,Groovy代码既能够与java代码很好地结合,也能够用于扩展现有的代码。
Gradle有如下特点:
Gradle支持多工程构建和局部构建Gradle支持远程或本地依赖管理:支持从远程maven仓库(项目构建工具、软件项目管理综合工具)、nexus私服(局域网内一种特殊的远程仓库)、ivy仓库(管理项目依赖的工具)以及本地仓库获取依赖Gradle与Ant、Maven兼容Gradle可轻松迁移:Gradle适用于任何结构的工程,可以在同一个开发平台平行构建原工程和Gradle工程Gradle使用灵活:Gradle的整体设计是以作为一种语言为导向的,而非成为一个严格死板的框架Gradle免费开源Gradle很好的与IDE集成Gradle可以更容易地集成到自动化构建系统
Android Studio下项目构建的Gradle配置
在Android Studio下创建一个Android项目,并切换到Project视图下,可以看到下图的项目结构。
红框标记就是项目中Gradle相关的配置文件,下面我们从app模块下的build.gradle开始对各个配置文件进行分析。
一、app Module下的build.gradle文件说明
app这个Module下的gradle配置文件,算是整个项目最主要的gradle配置文件,主要配置应用程序属性、配置应用程序签名、配置应用程序特性(渠道)、配置应用程序构建类型和配置应用程序依赖,下图是默认生成的文件内容:
1. 应用插件apply plugin总共有三种类型值,分别如下:
apply plugin: ‘com.android.application’//这表示此module是一个可运行的应用程序,可以直接run的apply plugin: ‘com.android.library’//这表示此module是一个安卓依赖库的工程,不可直接runapply plugin: ‘java’//这表示此module是一个java项目,在此module中只能使用java的api
2. 关于android闭包,
其默认有compileSdkVersion、buildToolsVersion、defaultConfig闭包和buildTypes闭包。
compileSdkVersion和buildToolsVersion是两个关于版本描述的参数
compileSdkVersion 25//指定编译版本,开发采用的sdk版本buildToolsVersion “25.0.2”//编译时采用的构建工具的版本
defaultConfig闭包参数说明
applicationId “com.jointem.variantpackaging”//应用的id,这里决定应用的唯一标识minSdkVersion 17//决定此应用可运行的安卓系统最低版本targetSdkVersion 25//决定此应用可运行的安卓系统最高版本versionCode 1//应用版本号,更新需要,新包的值要大于老包的方可更新versionName ‘1.0’//应用版本名,通常用于显示testInstrumentationRunner”andrid.support.test.runner.AndroidJUnitRunner”//Android单元测试test runner
buildTypes闭包参数说明
关于构建类型buildType,默认有release和debug两种,默认只显示release方式,一般是正式发布的包。
minifyEnabled false//混淆开关proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’// 指定混淆文件及混淆文件规则配置文件的位置
3.关于模块依赖dependencies
compile fileTree(include: [‘*.jar’], dir: ‘libs’)//编译文件树(编译依赖libs目录下所有jar)androidTestCompile(‘com.android.support.test.espresso:espresso-core:2.2.2’, { exclude group: ‘com.android.support’, module: ‘support-annotations’ })compile ‘com.android.support:appcompat-v7:24.2.1’//是从repository(默认是jCenter())里下载一个依赖包进行编译并打包compile ‘com.android.support.constraint:constraint-layout:1.0.0-beta5’testCompile ‘junit:junit:4.12’// 仅仅是针对单元测试代码的编译编译以及最终打包测试apk时有效,而对正常的debug或者release apk包不起作用compile project(‘:andr-library’)//是将另一个module进行编译并打包
其实,app下的脚本对应的是项目的Project Structure对话框中的设置,从左到右依次是属性、签名、渠道特性、构建类型和依赖,快捷键Ctrl+Shift+Alt+S(Windows/Linux),如下。
二、library Module下的build.gradle配置
除了app Module,每一个Module也都有一个gradle配置文件,语法都一样,区别在于开头声明的是apply plugin: ‘com.android.library’,表明该Module是以依赖模块的形式存在。
三、全局配置文件
所有的全局配置文件都会放置在项目的根目录下,包括忽略文件、本地配置文件、gradlew的批处理文件以及项目gradle相关的配置文件。
1.gradle配置文件gradle-wrapper.properties,默认内容如下:
#Thu Mar 09 16:27:37 CST distributionBase=GRADLE_USER_HOMEdistributionPath=wrapper/distszipStoreBase=GRADLE_USER_HOMEzipStorePath=wrapper/distsdistributionUrl=https\:///distributions/gradle-3.3-all.zip
此配置文件中主要声明了gradle的目录与下载路径以及当前项目使用的gradle版本,这些默认的路径我们一般不会更改的,这个文件里指明的gradle版本不对也是很多导包不成功的原因之一。
2.关于project下build.gradle配置文件
整个项目的gradle基础配置文件,用来配置项目的构建任务,内容如下:
// Top-level build file where you can add configuration options common to all sub-projects/modules.// 项目构建文件,可以在各子项目/模块添加常用的配置选项。buildscript { //Android插件从这个仓库下载repositories {jcenter()//依赖仓库源的名称,兼容maven的远程中央仓库} //项目依赖dependencies { //android gradle插件classpath 'com.android.tools.build:gradle:2.3.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files}}allprojects { //此处配置Project中默认的仓库源,包括每个module的依赖,无需每个module单独配置repositories {jcenter()}}//打包前执行clean任务//任务类型是Delete//clean任务就是删除项目根目录下的build目录中的文件task clean(type: Delete) {delete rootProject.buildDir}
3.关于Gradle配置文件gradle.properties
gradle.properties是Gradle的配置文件,build.gradle通过读取这个文件配置的参数来进行相应构建,可在此配置文件中配置一些全局参数(全局代理)。默认文件内容如下:
# Project-wide Gradle settings.# IDE (e.g. Android Studio) users:# Gradle settings configured through the IDE *will override*# any settings specified in this file.# For more details on how to configure your build environment visit# /docs/current/userguide/build_environment.html# 配置守护进程的jvm参数# Specifies the JVM arguments used for the daemon process.# The setting is particularly useful for tweaking memory .gradle.jvmargs=-Xmx1536m#配置完成后,Gradle将在并行模式下运行(并行编译)# When configured, Gradle will run in incubating parallel mode.# This option should only be used with decoupled projects. More details, visit#/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects# org.gradle.parallel=true
4.关于全局配置文件setting.gradle
默认文件内容include ‘:app’。是项目的全局配置文件,主要声明一些需要加入构建的模块。在Android studio中通常都是默认自动在此文件中添加依赖的module。
Android Studio下的依赖方式
一、Project Structure
按快捷键Ctrl+Shift+Alt+S(Windows/Linux),打开Project Structure弹窗。
在Dependencies下有个scope,这里可以选择依赖的方式,可选项有Compile、Provided、APK、Test compile、Debug compile和Release compile,下面分别对这些可选项进行简单说明。
Compile:是对所有的build type以及favlors都会参与编译并且打包到最终的apk文件中,是从repository(默认是jCenter())里下载一个依赖包进行编译并打包。Provided:Provided是对所有的build type以及favlors只在编译时使用,类似eclipse中的external-libs,只参与编译,不打包到最终apk,是提供给那些只编译不打包场景的命令。就是我在编译的时候对某一个jar文件有依赖,但是最终打包apk文件时,我不想把这个jar文件放进去,可以用这个命令。APK:只会打包到apk文件中,而不参与编译,所以不能再代码中直接调用jar中的类或方法,否则在编译时会报错。Test compile:仅仅是针对单元测试代码的编译编译以及最终打包测试apk时有效,而对正常的debug或者release apk包不起作用。Debug compile:仅仅针对debug模式的编译和最终的debug apk打包。Release compile:仅仅针对Release 模式的编译和最终的Release apk打包。
二、关于Compile的两个子参数:
compile files:是从本地的libs目录下寻找picasso-2.4.0.jar这个文件进行编译并打包。类似的命令有compile fileTree(dir: 'libs', include: '*.jar')
,即,将libs目录下所有jar文件进行编译并打包。compile project:是将另一个module(等同eclipse中的library)进行编译并打包。打出多变体包
一、为什么要打包变体包?
在开发过程中经常遇到多个环境切换的问题,比如,正在连接测试环境进行调试,此时又想看生产环境的数据显示,通常的处理方式是卸掉测试环境的然后运行一个生产环境的包。我们都知道,build一个大项目,直到安装到手机上,整个过程是很耗时的。如果同一台手机上可以同时安装同一个应用的多个不同环境的apk,那么,当想看其它环境的数据时,就不需要重新卸载再安装了(同理,同一应用,需要不同版本的安装包[免费版/收费版]时,也可以这样处理,而无需为不同版本创建不同的分支)。
二、打包变体包的条件
在创建完一个项目后,我们在app这个module下的build.gradle中的android节点下defaultConfig节点中,可以看到一个applicationId属性,默认的 applicationId 和 AndroidManifest.xml 中的 package 属性是相同的。applicationId 和 packageName 它们各自代表什么?为何会是相同的呢?其实,package 代表了 java 代码中的包名,在应用中的资源,就是通过package标识的(比如R文件,包名.R);applicationId 则代表了应用中的唯一标识,和应用签名一起用来区别于其他应用。
在手机上,系统同样是通过applicationId和签名来标识一个app的。所以,我们只要在打包apk时,使得应用之间的applicationId和签名各不相同,就能够实现同一个应用的不同变体同时安装在同一台手机上了。同时,为了更好的区分给个变体应用,我们还可以通过对占位符的使用,使用gradle配置不同的资源文件、不同的应用名称与图标、不同的java文件等有区别的属性,打出不同的变体包。
三、打出变体包的步骤
1.配置签名、渠道(applicationId)
选择app module,选择Signing选项卡,首先配置好了这两个变体版本的签名文件,文件名可任意取(见名知意)。
签名属性字段描述:
keyAlias//指定签名文件的别名keyPassword//指定签名文件的别名配对密码storeFile//签名文件路径storePassword//签名文件的密码
切换到Flavors选项卡,配置变体包的相关属性,由于下一步创建资源文件夹时,需要与这里的文件名对应,所以此处的取名尽量简约。这里我创建两个命名dev和rea的Flavor,所有的Flavor都会复写defaultConfig中的属性,所以可以看到我并没有填写其中的一些属性。在这里非常关键的一点,是对不同的变体设置不同的applicationId,并选择对应的Signing Config。
2.新建不同变体的sourceSet
在修改完变体的配置文件后,我们还需要再项目的src文件夹下,新建以我们的Flavor名称命名的文件夹,并在这些文件夹下新建如main中相同的目录结构。
我们正常编写项目都是写在main这个sourceSet下的,但是如果我们的项目的变体有不同的资源文件、Java文件时,我们就需要使用不同的sourceSet来区别开。
需要注意的是,Flavor下的资源文件会与main中的合并,如果存在重复,则Flavor中优先级高于main中。我们可以将不同变体中共用的资源存放在main中,只将不同的内容存放在flavor的sourceSet中。
如果不同变体有内容不同的Java文件则要注意,需要将这个Java文件放置到每个flavor 的sourceSet文件夹下,main中不可以有这个Java文件,如果main中也存在此文件,编译时会提示文件重复。比如说有两个变体,有着不同的TargetActivity.java,那么main中就不能有这个文件了,需要把这个Java文件放到各个flavor的sourceSet下,同时这个Java文件在sourceSet中要按照main中的包结构保存。
3.关于配置不同的launcher图标和应用名
通过之前的操作,已经可以有效区分变体包的applicationId、Signing Config和java文件,那么应用logo和name又该如何处理呢,这里有两种方法。
1)配置不同的资源:我们可以使用类似于处理java文件的方法,在不同的sourceSet中配置string.xml中app_name属性,在mipmap文件夹中放置对应的ic_app.png图标资源。不过当我们需要更换启动图和应用名而变体包又比较多的情况下,这种方法会比较麻烦,因为我们要到每一个sourceSet资源文件下去对应的修改,如果使用占位符的方式,那么会变得简单一些。
2)使用占位符的方式:在AndroidManifest文件中使用占位符然后在flavor中直接配置,在flavor中使用的属性是manifestPlaceholderss(manifestPlaceholders =[NAME1:VALUE1]),而图标资源和应用名称我们都可以直接放置到main中。
结果如下图:
四、Debug时选择变体
1.选择要调试的应用
通过之前的操作,已经成功配置了多个变体,那么问题来了,这么多个变体,我们在debug的时候,我们怎么选择要debug的变体呢?这里有两种方式进行切换。
选择Build->Select Build Variant,在左下角会显示出Build Variant视图,点击选择要编译的变体。
另一种方式则是直接点击左下角Build Variant选下卡,之后的操作同上。
2.需要注意的的地方
在这里可以看到有4个变体,这是为什么呢?我们明明只配置了两个变体呀?在这需要提到Build Type配置,这个选项卡下默认有两个类型,分别是debug和release,变体包的数量正是(build type数量)*(flavor数量)。当你选择完要编译的变体后,会发现未被选中的变体下会报找不到资源的错误,这是很正常的,当被选中之后就会变成正常的工程文件夹样式了,其这种报错也并不会影响我们进行批量打包。
五、常用gradlew命令
首次运行命令行,没有gradle的要下载的哦,下载需要的时间根据网络状况而定。
1.八个常用命令:
./gradlew -v //查看gradle版本./gradlew assembleDebug //编译并打出Debug版本的包./gradlew assembleRelease //编译并打出Release版本的包./gradlew build //执行检查并编译打包,打出所有Release和Debug的包./gradlew clean //删除build目录,会把app下面的build目录删掉./gradlew installDebug //编译打包并安装Debug版本的包./gradlew uninstallDebug //卸载Debug版本的包./gradlew -info //使用-info查看任务详情
2.命令行终端Terminal下执行打包命令
我们直接利用./gradlew build打出所有的变体包,在Terminal终端下键入./gradlew build命令,需要等待大概20秒钟左右,当看到终端打印出BUILD SUCCESSFUL,说明打包任务执行完成,打开指定的apk生成目录(默认app/build/outputs/apk),就可以看到已经打出的apk。
将两个release包都安装到同一台手机,可以发现能同时存在,并且都能正常打开运行。
3.关于打包需要注意的坑
如果项目中存在使用Library Module,并且Library Module中manifest下的application也存在与app Module下的application相同的属性标签,那么会报manifest.xml合并错误的提示,如下。
原因:这是因为AS的Gradle插件默认会启用Manifest Merger Tool,若Library项目中也定义了与主项目相同的属性(例如默认生成的android:icon和android:theme),则此时会合并失败,并报上面的错误。处理办法:在Manifest.xml的application标签下添加tools:replace=”android:icon, android:theme”(多个属性用,隔开,并且记住在manifest根标签上加入xmlns:tools=”/tools”,否则会找不到namespace哦)。
注:本篇博客纯属个人笔记,如果错误之处,还望帮忙指正,谢谢!
以上就是Android Studio下项目构建的Gradle配置及打包应用变体的全部内容了,更多内容请关注:CPP学习网_CPP大学
本文固定链接:CPP学习网_CPP大学-Android Studio下项目构建的Gradle配置及打包应用变体
如果觉得《Android Studio下项目构建的Gradle配置及打包应用变体》对你有帮助,请点赞、收藏,并留下你的观点哦!