赞
踩
Gradle是一个自动化构建工具,采用Groovy的Domain Specific Language(领域特定语言)来描述和控制构建逻辑。具有语法简洁、可读性强、配置灵活等特点。基于Intellij IDEA社区版本开发的Android Studio天生支持Gradle构建程序。Groovy是一种基于JVM的敏捷开发语言,结合了Phthon、Ruby和Smalltalk的许多强大特性。同时,Groovy代码既能够与java代码很好地结合,也能够用于扩展现有的代码。
Gradle有如下特点:
在Android Studio下创建一个Android项目,并切换到Project视图下,可以看到下图的项目结构。
红框标记就是项目中Gradle相关的配置文件,下面我们从app模块下的build.gradle开始对各个配置文件进行分析。
app这个Module下的gradle配置文件,算是整个项目最主要的gradle配置文件,主要配置应用程序属性、配置应用程序签名、配置应用程序特性(渠道)、配置应用程序构建类型和配置应用程序依赖,下图是默认生成的文件内容:
apply plugin:
‘com.android.application’//这表示此module是一个可运行的应用程序,可以直接run的
apply plugin: ‘com.android.library’//这表示此module是一个安卓依赖库的工程,不可直接run
apply plugin: ‘java’//这表示此module是一个java项目,在此module中只能使用java的api
其默认有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’// 指定混淆文件及混淆文件规则配置文件的位置
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),如下。
除了app Module,每一个Module也都有一个gradle配置文件,语法都一样,区别在于开头声明的是apply plugin: ‘com.android.library’,表明该Module是以依赖模块的形式存在。
所有的全局配置文件都会放置在项目的根目录下,包括忽略文件、本地配置文件、gradlew的批处理文件以及项目gradle相关的配置文件。
#Thu Mar 09 16:27:37 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
此配置文件中主要声明了gradle的目录与下载路径以及当前项目使用的gradle版本,这些默认的路径我们一般不会更改的,这个文件里指明的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
}
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
# http://www.gradle.org/docs/current/userguide/build_environment.html
# 配置守护进程的jvm参数
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.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
#http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
默认文件内容include ‘:app’。是项目的全局配置文件,主要声明一些需要加入构建的模块。在Android studio中通常都是默认自动在此文件中添加依赖的module。
按快捷键Ctrl+Shift+Alt+S(Windows/Linux),打开Project Structure弹窗。
在Dependencies下有个scope,这里可以选择依赖的方式,可选项有Compile、Provided、APK、Test compile、Debug compile和Release compile,下面分别对这些可选项进行简单说明。
compile fileTree(dir: 'libs', include: '*.jar')
,即,将libs目录下所有jar文件进行编译并打包。在开发过程中经常遇到多个环境切换的问题,比如,正在连接测试环境进行调试,此时又想看生产环境的数据显示,通常的处理方式是卸掉测试环境的然后运行一个生产环境的包。我们都知道,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文件等有区别的属性,打出不同的变体包。
选择app module,选择Signing选项卡,首先配置好了这两个变体版本的签名文件,文件名可任意取(见名知意)。
签名属性字段描述:
切换到Flavors选项卡,配置变体包的相关属性,由于下一步创建资源文件夹时,需要与这里的文件名对应,所以此处的取名尽量简约。这里我创建两个命名dev和rea的Flavor,所有的Flavor都会复写defaultConfig中的属性,所以可以看到我并没有填写其中的一些属性。在这里非常关键的一点,是对不同的变体设置不同的applicationId,并选择对应的Signing Config。
在修改完变体的配置文件后,我们还需要再项目的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中的包结构保存。
通过之前的操作,已经可以有效区分变体包的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的时候,我们怎么选择要debug的变体呢?这里有两种方式进行切换。
首次运行命令行,没有gradle的要下载的哦,下载需要的时间根据网络状况而定。
- ./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查看任务详情
我们直接利用./gradlew build打出所有的变体包,在Terminal终端下键入./gradlew build命令,需要等待大概20秒钟左右,当看到终端打印出BUILD SUCCESSFUL,说明打包任务执行完成,打开指定的apk生成目录(默认app/build/outputs/apk),就可以看到已经打出的apk。
将两个release包都安装到同一台手机,可以发现能同时存在,并且都能正常打开运行。
如果项目中存在使用Library Module,并且Library Module中manifest下的application也存在与app Module下的application相同的属性标签,那么会报manifest.xml合并错误的提示,如下。
注:本篇博客纯属个人笔记,如果错误之处,还望帮忙指正,谢谢!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。