2018-08-17 Android Gradle(1)
Android Gradle 插件分类
在android中有三类工程,一类是app应用工程,它可以生成一个可运行的apk应用;一类是Library库工程,他可以生成AAR包给其他的App工程公用,就和我们的Jar一样,但是它包含了Android的资源等信息,是一个特殊的Jar包;最后一类是Test测试工程,用于对APP工程或者Library库工程进行单元测试
- APP插件id:com.android.application
- Library插件id:com.android.library
- Test插件id:com.android.test
通过上面3种不同的插件,就可以配置我们的工程是一个Android App工程,还是一个Android Library工程,或者是一个Android Test测试工程
要应用一个插件就必须要知道它的插件id,如果是第三方插件,还需要配置它们的依赖classpath,Android Gradle插件就是属于第三方插件,他托管在jcenter上,所以应用之前,需要先配置依赖classpath
buildscript {
repositories{
jcenter()
}
dependencies{
classpath 'com.android.tools.build:gradle:1.5.0'
}
}
buildscript{}闭包可以写在根工程的build.gradle脚本文件中,这样所有的子工程就不用重复配置了
配置好后,就可以在App工程中用了
apply plugin:'com.android.application'
android{
compileSdkVersion 23
buildToolsVersion "23.0.1"
}
android{}是Android插件提供的一个扩展类型
Android Gradle工程的配置,都是在android{}中,这是唯一的一个入口,通过它,可以让我们自定义一个Android Gradle工程.
compileSdkVersion是编译所依赖的Android Sdk的版本
buildToolsVersion是构建该Android工程所用构建工具的版本
具体实现如下
extension=project.extensions.create('android',getExtensionClass(),(ProjectInternal)project,instantiator,
androidBuilder,sdkHandler,buildTypeContainer,productFlavorContainer,signingConfigContainer,
extraModelInfo,isLivraty())
defaultConfig
defaultConfig是默认的配置,它是一个ProductFlavor,ProductFlavor允许我们根据不同的情况同时生成多个不同的APK包,默认配置中
applicationId 是配置我们的包名
minSdkVersion是最低支持的Android系统的API Level
targetSdkVersion 表明我们是基于那个Androi版本开发的
versionCode表明我们的APP应用内部版本号,一般用于控制App升级
versionName 表明我们的APP应用的版本名称
buildTypes
buildTypes 是一个域对象,和SourceSet一样,里面有main,test,release,debug等,我们可以在buildTypes{}里新增任意多的我们需要构建的类型
minifyEanbled 是否为该构建类型启用混淆,false表示不启用
proguardFiles 当我们启用混淆时,所使用的proguard的配置文件,可以根据接收的参数同时配置一个或者多个配置文件如
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
getDefaultProguardFile是Android扩展的一个方法,用来获取AndroidSDK 目录下默认的proguard配置文件 文件名就是传入的参数名proguard-android.txt
signingConfig
配置默认的签名信息,对生成的App签名,是ProductFlavor的一个属性,可以直接对其进行配置,方法原型如下
public ProductFlavor setSigningConfig(SigningConfig signingConfig){
msigningConfig=signingConfig
ruturn this;
}
public SigningConfig getsigningConfig(){
return mSigningConfig;
}
默认配置如下
signingConfigs {
release {
//签名证书文件,打正式包时,自己生成
storeFile file('G:/xxx/xxx/xxx.jks')
//签名证书密码
storePassword 'xxx'
//签名证书中的秘钥别名
keyAlias 'xxx'
//签名证书中的该秘钥的密码
keyPassword 'xxx'
}
debug {
storeFile file('G:/xxx/xxx/xxx.jks')
storePassword 'xxx'
keyAlias 'xxx'
keyPassword 'xxx'
}
}
multiDexEnabled
是buildType的一个属性,用于配置该BuildType是否启用自动拆分多个Dex的功能,一般用于程序中代码太多,超过65536个方法的时候,拆分为多个Dex的处理,接收boolean值
shrinkResources
是buildType的一个属性,用于配置是否自动清理未使用的资源,默认为false
zipalign
zipalign是Andoroid提供的一个整理优化apk文件的工具,它能提高系统和应用的运行效率,更快的读写apk中的资源,降低内存的使用,所以对于要发布的app,再发布之前一定要使用zipalign进行优化
如果想在release模式开启zipalign优化,需要进行如下配置
android{
buildTypes{
release{
aipAlignEnabled true
}
debug{
}
}
}
批量修改生成的apk文件名
既然要修改生成的apk文件名,那么就要修改Android Gradle打包的输出,为此,Android对象为我们提供了下列3个属性
application Variants 仅仅适用于Android 应用的Gradle插件
library Variants 仅仅适用于 Android库 Gradle插件
testVariants 以上两种Gradle插件都适用
以上三个属性都返回DomainObjectSet对象集合,如下例
buildTypes {
release {
xxx...
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
def fileName = "dayuyoupin-${defaultConfig.versionCode}-${defaultConfig.versionName}-${releaseTime()}-${variant.productFlavors[0].name}.apk"
//output.outputFile = new File(outputFile.parent, fileName)
outputFileName = fileName
}
}
}
}
debug {
signingConfig signingConfigs.debug
}
}
application Variants 是一个DomainObjectCollection集合,我们可以通过all方法进行遍历,遍历的每一个variant都是一个生成的产物
ext{}
程序中ext{}快表明要为当前project创建扩展属性,以供其他脚本引用,就像java里的变量一样,创建好以后,可以在build.gradle中引用它,如下先创建一个version.gradle,然后引用
version.gradle
ext.name="xxx"
ext{
appVersionCode=1
appVersionName="1.0.0"
}
build.gradle 中引用
build.gradle
apply plugin:'java'
apply from: 'version.gradle'
引用java插件时,java就是插件的plugin id
插件可以分为脚本插件和二进制插件,from区分与脚本插件和二进制插件,引用第三方发布的jar包的一些二进制插件时,就必须在项目根目录的build.gradle中的buildscript{}中配置其classpath
隐藏签名信息
前面我们把项目的签名信息放在项目中,托管在git上,这样做虽然非常方便,但存在着一定的安全隐患,如果要安全隐藏,最好的办法就是将其放在服务器上,要实现这个,还得有自己的专门用于打包发版的服务器,下面以使用环境变量的方式为例
singingConfigs{
def appStoreFile=System.getenv("STORE_FILE")
def appStorePassword=System.getenv("STORE_PASSWORD)
def appKeyAlias=System.getenv("KEY_PASSWORD"))
release{
storeFile file(appStoreFile)
storePassword appStorePassword
keyAlias appKeyAlias
keyPassword appkeyPassword
}
}
release{
signingConfig signigConfigs.release
}
动态配置AndroidManifest文件
应用于多渠道打包,如下
build.gradle
productFlavors{
google{}
baidu{}
}
productFlavors.all{ flavor ->
mainfestPlaceholders.put("UMENG_CHANNEL",name)
}
mainfest中
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
通过all函数遍历每一个ProductFlavor.然后把它们的name作为友盟中渠道的名字,再利用Android Gradle中提供的mainfestPlaceholders占位符的应用方式,可以动态替换掉AndroiMainfest文件中任何${var}格式的占位符
BuildConfig
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.deepbaytech.tao";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "baidu";
public static final int VERSION_CODE = 0;
public static final String VERSION_NAME = "1.3.7.debug";
}
DEBUG 用于标记是debug还是release模式,其余的还有包名,当前构建的类型,是debug还是release,当前构建的渠道,当前的版本号以及版本名称,这些差不多就是我们当前构建渠道的基本应用信息,都是常量,相比于我们获取这些信息的其他方式,无疑要方便许多
一般在开发过程中都会输出日志进行调试,一般只有我们自己开发中才会打印日志,发布版本后就 不打印了,也就是我们需要一个标记是debug还是release模式的开关,这就是buildConfig.DEBUG,在debug模式下时true.在release模式下它的值会自动变为false,不用我们自己改动,Android会自动帮我们修改,非常方便.
当然我们也可以自己定义,在BuildConfig中新增一些常量.一般利用android Gradle提供的buildConfigField(String type,String name,String value) 来动态配置.例子如下
假如我们有baidu和google两个渠道,发布的时候会有这两个渠道包,当我们安装baidu渠道包的时候打开的是baidu首页,当我们安装google渠道包的时候,打开的是google首页,从这个思路分析,我们只要添加一个字段WEB_URL,在百度渠道包下时http://www.baidu.com,在google渠道包下值为http://www.google.com即可:
productFlavors{
google{
buildConfigField 'String','WEB_URL','"http://www.google.com"'
}
baidu{
buildConfigField 'String','WEB_URL','"http://www.baidu.com"'
}
}
release和debug也可以配置,如下
buildType{
debug{
buildConfigField 'String','NAME','"value"'
}
}