Android Gradle 打包技巧
首先看一下一个完整的build.gradle文件
[代码]java代码:apply plugin:'com.android.application' android {compileSdkVersion26buildToolsVersion"26.0.1"//默认配置defaultConfig {applicationId"manager.rbyj.wisemax.com.yunyouyou"minSdkVersion21targetSdkVersion26versionCode1versionName"1.0"testInstrumentationRunner"android.support.test.runner.AndroidJUnitRunner"}//编译类型buildTypes {debug {minifyEnabledfalseproguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'manifestPlaceholders = ["jpush_appkey":"a57903f0d0d3b0e935a808aa"]}release {minifyEnabledfalseproguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'manifestPlaceholders = ["jpush_appkey":"a57903f0d0d3b0e935a808bb"]}}//编译变体productFlavors {baidu {applicationId"manager.rbyj.wisemax.com.yunyouyou"versionCode1versionName"1.0.0"buildConfigField'String','IP','"192.168.0.112"'buildConfigField'String','PORT','"8081"'}_360 {applicationId"manager.rbyj.wisemax.com.yunyouyou"versionCode2versionName"2.0.0"buildConfigField'String','IP','"192.168.0.113"'buildConfigField'String','PORT','"8082"'}yingyongbao {applicationId"manager.rbyj.wisemax.com.yunyouyou"versionCode3versionName"3.0.0"buildConfigField'String','IP','"192.168.0.114"'buildConfigField'String','PORT','"8083"'}} //签名配置signingConfigs {release {try {storeFile file("keystore/yun_you_you.jks")//这里替换成你自己项目生成的keystore的存储路径storePassword"rzhj123456"keyAlias"YunYouYou"keyPassword"rzhj123456"}catch (ex) {throw new InvalidUserDataException(ex.toString())}/*keyAlias 'YunYouYou'keyPassword 'rzhj123456'storeFile file('D:/YunYouYou/app/keystore/yun_you_you.jks')storePassword 'rzhj123456'*/}debug {try {storeFile file("keystore/yun_you_you.jks")storePassword "rzhj123456"keyAlias "YunYouYou"keyPassword "rzhj123456"} catch (ex) {throw new InvalidUserDataException(ex.toString())}/*keyAlias 'YunYouYou'keyPassword 'rzhj123456'storeFile file('D:/YunYouYou/app/keystore/yun_you_you.jks')storePassword 'rzhj123456'*/}} //输出指定名称apkandroid.applicationVariants.all { variant ->variant.outputs.each { output ->def outputFile = output.outputFileif (outputFile !=null && outputFile.name.endsWith('.apk')) {File outputDirectory =new File(outputFile.parent);def fileNameif (variant.buildType.name =="release") {//apk名称为:前缀_渠道名称_版本号_版本名称_模式.apkfileName ="APP_${variant.productFlavors[0].name}_${versionCode}_${versionName}_release.apk"}else {fileName ="APP_${variant.productFlavors[0].name}_${versionCode}_${versionName}_debug.apk"}output.outputFile =new File(outputDirectory, fileName)}}}} dependencies {compile fileTree(include: ['*.jar'], dir:'libs')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:26.+'compile'com.android.support.constraint:constraint-layout:1.0.2'testCompile'junit:junit:4.12'}
productFlavors{ } 是配置多渠道打包的.(我们有三个 baidu、_360、yinyongbao)
1).productFlavors{ } 与 buildTypes{ }里面的配置是多对多的关系。
2).productFlavors{ } 其实是defaultConfig{ }的子集
defaultConfig {}中的属性在productFlavors{}中都可以单独设置,若重复会以productFlavors{}中的属性为最终属性.
a.可以对单独的productFlavors{ } 设置applicationId进而达到多个相同应用安装到同一台设备(现applicationId为唯一标识,区别于packageName)
b.对单独的productFlavors{ }进行一些单独的配置或者操作
eg:单独对company的flavors进行了applicationId、minSdk、和JUnit测试限制操作,这样打出的包只会对company的有影响,其他的flavors无影响
buildConfigField自定义配置
buildConfigField是用于解决不同渠道版本服务地址不同或者一些Log打印需求控制的.
形式:buildConfigField "String", "IP", "172.0.1.113"
三个字段分别表示为: 自定义字段类型 自定义字段名 自定义字段值
将buildConfigField写入到productFlavors中在打包编译时就会单独的编入进去(PS.请注意单双引号的使用,对于链接需要额外的单引号buildConfigField的放置位置很灵活,如果Flavors的buildConfigField是一样的话,直接放入到debug{}和release{}中即可.)
Java代码中调用方法(BuildConfig.自定义的属性名) eg: String ip = BuildConfig.IP;
--------------------------------------------------------------------------------------------------------------------------------------------------------
开发中很多时候我们会遇到这种场景,比如说:在用到一个第三方sdk,但是这个sdk并没有区分开发环境和线上环境,这时候我们就可能会申请两个不同的key标识,而且很多key标识都只能在androidmanifest里面配置。所以每次上线生成apk就必须手动去更改key标识,如果渠道版本少也还好,打包速度快也还行,需要区分环境的的key标识相对较少也还不错 ,但是如果你一项都沾不到边,到时忘记哪个key忘记替换了,一定会有种“身体被掏空的赶脚”,别问我为什么知道,感觉身体被掏空!!!
manifestPlaceholders 可以替换androidmanifest文件中的标签,可作为快速渠道打包替换渠道名的一种方式,也可以自定义标签用来替换需要的文本,多作为不同环境不同key的修改。
以极光推送为例,首先在androidmainfest文件中配置一个节点:
[代码]xml代码:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[代码]xml代码://输出指定名称apkandroid.applicationVariants.all { variant ->variant.outputs.each { output ->def outputFile = output.outputFileif (outputFile != null && outputFile.name.endsWith('.apk')) {File outputDirectory = new File(outputFile.parent);def fileNameif (variant.buildType.name == "release") {//apk名称为:前缀_渠道名称_版本号_版本名称_模式.apkfileName = "APP_${variant.productFlavors[0].name}_${versionCode}_${versionName}_release.apk"} else {fileName = "APP_${variant.productFlavors[0].name}_${versionCode}_${versionName}_debug.apk"}output.outputFile = new File(outputDirectory, fileName)}}}
这个是修改打包文件的名称的,大家可以跟进自己的需求修改!
----------------------------------------------------------------------------------------------------------------------------------
[代码]xml代码://签名配置signingConfigs {release {try {storeFile file("keystore/yun_you_you.jks")//这里替换成你自己项目生成的keystore的存储路径storePassword "rzhj123456"keyAlias "YunYouYou"keyPassword "rzhj123456"} catch (ex) {throw new InvalidUserDataException(ex.toString())}/*keyAlias 'YunYouYou'keyPassword 'rzhj123456'storeFile file('D:/YunYouYou/app/keystore/yun_you_you.jks')storePassword 'rzhj123456'*/}debug {try {storeFile file("keystore/yun_you_you.jks")storePassword "rzhj123456"keyAlias "YunYouYou"keyPassword "rzhj123456"} catch (ex) {throw new InvalidUserDataException(ex.toString())}/*keyAlias 'YunYouYou'keyPassword 'rzhj123456'storeFile file('D:/YunYouYou/app/keystore/yun_you_you.jks')storePassword 'rzhj123456'*/}}
这个是签名文件配置,没什么好说的。注意下这个路径就ok了(storeFile file("keystore/yun_you_you.jks"))换成自己的路径即可。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
友情连接:
1.Gradle 中 buildConfigField的巧妙应用(http://blog.csdn.net/u011153817/article/details/50772496)
2.通过配置Flavors和自定义buildConfigField进行多个服务器地址打包(http://blog.csdn.net/qxf5777404/article/details/51580431)
3.Android Gradle manifestPlaceholders 的妙用(http://blog.csdn.net/qq_21793463/article/details/52069127)
4.AndroidStudio打包生成APK 指定文件名(http://blog.csdn.net/u011445031/article/details/72731180)