Android Gradle 打包技巧
首先看一下一个完整的build.gradle文件
[代码]java代码:
apply plugin: 'com.android.application' android { compileSdkVersion 26 buildToolsVersion "26.0.1" //默认配置 defaultConfig { applicationId "manager.rbyj.wisemax.com.yunyouyou" minSdkVersion 21 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } //编译类型 buildTypes { debug { minifyEnabled false proguardFiles getDefaultProguardFile( 'proguard-android.txt' ), 'proguard-rules.pro' manifestPlaceholders = [ "jpush_appkey" : "a57903f0d0d3b0e935a808aa" ] } release { minifyEnabled false proguardFiles getDefaultProguardFile( 'proguard-android.txt' ), 'proguard-rules.pro' manifestPlaceholders = [ "jpush_appkey" : "a57903f0d0d3b0e935a808bb" ] } } //编译变体 productFlavors { baidu { applicationId "manager.rbyj.wisemax.com.yunyouyou" versionCode 1 versionName "1.0.0" buildConfigField 'String' , 'IP' , '"192.168.0.112"' buildConfigField 'String' , 'PORT' , '"8081"' } _360 { applicationId "manager.rbyj.wisemax.com.yunyouyou" versionCode 2 versionName "2.0.0" buildConfigField 'String' , 'IP' , '"192.168.0.113"' buildConfigField 'String' , 'PORT' , '"8082"' } yingyongbao { applicationId "manager.rbyj.wisemax.com.yunyouyou" versionCode 3 versionName "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'*/ } } //输出指定名称apk android.applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith( '.apk' )) { File outputDirectory = new File(outputFile.parent); def fileName if (variant.buildType.name == "release" ) { //apk名称为:前缀_渠道名称_版本号_版本名称_模式.apk fileName = "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代码:
在bulidtypes节点下的release节点和debug节点下配置manifestPlaceholders,jpush_appkey对应的就是之前在androidmanifest文件配置的${jpush_appkey}的这个值。这样release版本和debug版本就会有不同的jpush_appkey了。---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[代码]xml代码:
//输出指定名称apk android.applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) { File outputDirectory = new File(outputFile.parent); def fileName if (variant.buildType.name == "release") { //apk名称为:前缀_渠道名称_版本号_版本名称_模式.apk fileName = "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)