近來公司有需求犬缨,同一套代碼喳魏,要打包N套APP,而且這些APP的軟件名稱遍尺,軟件圖標截酷,applicationId,版本號乾戏,甚至主頁都不一樣迂苛。之前都是單次修改,單次打包鼓择,可隨著需求越來越多三幻,需要打的包也會越來越多,單次打包費時費力呐能,很明顯已經(jīng)不再適合念搬,于是研究了一下抑堡,使用gradle成功實現(xiàn)了需要的功能,打包過程也變的更為簡單朗徊。
gradle是一個基于Apache Ant和Apache Maven概念的項目自動化建構(gòu)工具首妖。他可以幫助我們輕松實現(xiàn)多渠道打包的功能。
- 效果圖
- 項目結(jié)構(gòu)圖
- 項目結(jié)構(gòu)中build.gradle的具體內(nèi)容
apply plugin: 'com.android.application'
//打包時間
def releaseTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
//獲取local.properties的內(nèi)容
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
// 使用簽名文件進行簽名的兩種方式
// //第一種:使用gradle直接簽名打包
// signingConfigs {
// config {
// storeFile file('keyTest.jks')
// storePassword '123456'
// keyAlias 'HomeKey'
// keyPassword '123456'
// }
// }
//第二種:為了保護簽名文件爷恳,把它放在local.properties中并在版本庫中排除
// 有缆,不把這些信息寫入到版本庫中(注意,此種方式簽名文件中不能有中文)
signingConfigs {
config {
storeFile file(properties.getProperty("keystroe_storeFile"))
storePassword properties.getProperty("keystroe_storePassword")
keyAlias properties.getProperty("keystroe_keyAlias")
keyPassword properties.getProperty("keystroe_keyPassword")
}
}
// 默認配置
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0.1"
}
// 多渠道 的不同配置
productFlavors {
baidu{
// 每個環(huán)境包名不同
applicationId "com.shi.androidstudio.multichannel.baidu"
// 動態(tài)添加 string.xml 字段温亲;
// 注意棚壁,這里是添加,在 string.xml 不能有這個字段栈虚,會重名P渫狻!魂务!
resValue "string", "app_name", "百度"
resValue "bool", "auto_updates", 'false'
// 動態(tài)修改 常量 字段
buildConfigField "String", "ENVIRONMENT", '"我是百度首頁"'
// 修改 AndroidManifest.xml 里渠道變量
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
}
qq{
applicationId "com.shi.androidstudio.multichannel.qq"
resValue "string", "app_name", "騰訊"
resValue "bool", "auto_updates", 'true'
buildConfigField "String", "ENVIRONMENT", '"我是騰訊首頁"'
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "qq"]
}
xiaomi{
applicationId "com.shi.androidstudio.multichannel.xiaomi"
resValue "string", "app_name", "小米"
resValue "bool", "auto_updates", 'true'
resValue "drawable", "isrRank", 'true'
buildConfigField "String", "ENVIRONMENT", '"我是小米首頁"'
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
}
}
//移除lint檢測的error
lintOptions {
abortOnError false
}
buildTypes {
debug {
// debug模式下曼验,顯示log
buildConfigField("boolean", "LOG_DEBUG", "true")
//為已經(jīng)存在的applicationId添加后綴
applicationIdSuffix ".debug"
// 為版本名添加后綴
versionNameSuffix "-debug"
// 不開啟混淆
minifyEnabled false
// 不開啟ZipAlign優(yōu)化
zipAlignEnabled false
// 不移除無用的resource文件
shrinkResources false
// 使用config簽名
signingConfig signingConfigs.config
}
release {
// release模式下,不顯示log
buildConfigField("boolean", "LOG_DEBUG", "false")
// 為版本名添加后綴
versionNameSuffix "-relase"
// 不開啟混淆
minifyEnabled false
// 開啟ZipAlign優(yōu)化
zipAlignEnabled true
// 移除無用的resource文件
shrinkResources true
// 使用config簽名
// signingConfig signingConfigs.config
// 混淆文件位置
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// // 批量打包
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
//輸出apk名稱為:渠道名_版本名_時間.apk
def fileName = "${variant.productFlavors[0].name}_v${defaultConfig.versionName}_${releaseTime()}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
}
}
//項目依賴
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
}
- 項目結(jié)構(gòu)中l(wèi)ocal.properties的具體內(nèi)容
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=D\:\\Android_Studio\\SDK
#對應自己實際的證書路徑和名字头镊,在這里由于簽名文件是放在app目錄下蚣驼,因為沒有寫絕對路徑。
keystroe_storeFile=keyTest.jks
keystroe_storePassword=123456
keystroe_keyAlias=HomeKey
keystroe_keyPassword=123456
看完build.gradle和local.properties的具體內(nèi)容之后相艇,我們再來挑選幾個地方來具體說一下颖杏。
一. signingConfigs
在signingConfigs中主要是為打包配置簽名文件具體信息的,這里我使用了兩種方式坛芽,第一種方式把簽名文件的位置留储,storePassword ,keyAlias咙轩,keyPassword 等具體內(nèi)容都直接寫在其中获讳,然后使用gradle進行打包,第二種是通過通過使用local.properties文件來間接加載簽名文件的具體信息活喊。一般我們更傾向于第二種方法丐膝,這樣有助于保護我們的簽名文件(在local.properties中不能有中文)。
二. productFlavors
不同渠道的設(shè)置基本都是在 productFlavors 里設(shè)置的钾菊,在里面想要添加多少個渠道都可以帅矗。
修改app名稱
resValue "string", "app_name", "騰訊"
resValue "bool", "auto_updates", 'true'
通過resValue 我們可以在在 string.xml 里面添加了一個新的字段app_name,由于是添加煞烫,所以原來的string.xml 文件中不能存在app_name字段浑此,否則會報錯。
當然我們還可以添加布爾類型滞详,還可以為color.xml凛俱、dimen.xml添加一些我們需要的字段紊馏。
修改app圖標
當我們在productFlavors 中添加了不同渠道環(huán)境名稱之后,我們還可以mian文件夾同層級中建立和baidu蒲犬,qq朱监,xiaomi名稱對應的文件夾,并放入特定的圖標文件暖哨,當然我們還可以放入其他資源文件赌朋,甚至AndroidManifest.xml都可以放入,Gradle在構(gòu)建應用時篇裁,會優(yōu)先使用flavor所屬dataSet中的同名資源。所以赡若,在flavor的dataSet中添加同名的資源文件达布,會覆蓋默認的資源文件,這樣就能達到不同環(huán)境不同軟件圖標的功能逾冬。
簡單介紹就到這里了黍聂,做個筆記方便以后使用,如果"不小心"幫到別人了當然也是極好的了身腻。
最后附上github上的項目地址以及整個demo下載地址