Gradle配置及同一應用不同版本配置不同資原始檔,不同簽名,包名進行打包
阿新 • • 發佈:2019-02-19
公司的專案,一個專案也就是同一套程式碼要針對多個客戶打出多個版本的apk,不同版本的apk中一些程式碼是不同的,比如伺服器的地址,app的名字,圖片資源以及簽名檔案等都是不同的。剛開始的時候,把這些相同的程式碼,資原始檔提取出來,打包的時候進行替換就可以了,隨著客戶越來越多,每為一個客戶打包,替換一次資原始檔,很浪費時間,還容易出錯。其實,我們可以在build.gradle中進行配置,來解決問題。
我們先看一下build.gradle中的一些相關配置
上面是一些build.gradle的基本的配置,android { compileSdkVersion 25 buildToolsVersion "24.0.3" //預設的一些配置 defaultConfig { applicationId "com.app.springboot" //應用的包名 minSdkVersion 14 //支援的最低版本 targetSdkVersion 25 //目標版本 versionCode 1 versionName "1.0" } //debug和release版本的簽名配置 signingConfigs { release { storeFile file("D:/other/test.jks") storePassword "12345678" keyAlias "test" keyPassword "123456" } } //構建型別,通常有release和debug兩種 buildTypes { release { minifyEnabled false //是否開啟混淆 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release //指定打包時的簽名 } } //用來配置APP的不同版本 productFlavors{ demo1{ applicationId "com.app.demo1" //為不同版本指定的包名 manifestPlaceholders=[umeng_app_key:"替代的內容"] //可以替換清單檔案AndroidManifest中指定的內容 } demo2{ applicationId "com.app.demo2" manifestPlaceholders=[umeng_app_key:"替代的內容"] } } } //新增需要的依賴 dependencies { compile fileTree(dir: 'libs', include: ['*.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:25.0.1' testCompile 'junit:junit:4.12' compile 'com.squareup.okhttp:okhttp:2.6.0' }
因為我們的app需要打不同版本的包,不同版本的包需要配置不同的資原始檔和簽名檔案,所以在build.gradle中這樣配置
android { compileSdkVersion 25 buildToolsVersion "24.0.3" defaultConfig { applicationId "com.app.springboot" minSdkVersion 14 targetSdkVersion 25 versionCode 1 versionName "1.0" } //debug和release版本的簽名配置 signingConfigs { demo1{ storeFile file("D:/demo/demo1/demo1.jks") storePassword "12345678" keyAlias "test" keyPassword "123456" } demo2{ storeFile file("D:/demo/demo2/demo2.jks") storePassword "12345678" keyAlias "test" keyPassword "123456" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } //用來配置APP的不同版本 productFlavors{ demo1{ applicationId "com.app.demo1" manifestPlaceholders=[umeng_app_key:"替代的內容"] signingConfig signingConfigs.demo1 //指定打包時的簽名 } demo2{ applicationId "com.app.demo2" manifestPlaceholders=[umeng_app_key:"替代的內容"] signingConfig signingConfigs.demo2 } } // 針對不同的客戶,編譯不同的目錄, sourceSets{ demo1.res.srcDirs=['src/main/res-demo1'] //指定編譯的目錄 demo2.res.srcDirs=['src/main/res-demo2'] } }
如上,在sourceSets{}中,針對不同的客戶,編譯不同的目錄,不同的版本可以選擇不同的編譯目錄進行編譯,,如果指定一個目錄,其他目錄沒有指定,那麼就會把指定的目錄和預設的目錄一起打包到apk中。如果指定了res-demo1,打包的時候res-demo1會替換掉res下的同名檔案。
因為不同版本的簽名檔案也需要不同,所以在signingConfigs {}中為每個版本配置了一個簽名檔案,但是這種方法不太安全,建議不要在build.gradle檔案中寫上簽名檔案的密碼,因為build.gradle檔案一般都會整合到程式碼的版本控制中,這樣所有人都會有簽名檔案的密碼。所以應該把簽名檔案的密碼隔離起來,寫到一個配置檔案中,此配置檔案不包含在程式碼版本控制中,這樣其他開發者就不會知道簽名檔案的密碼。
我們先新建一個signing.properties檔案:
STORE_FILE=yourapp.keystore
STORE_PASSWORD=your password
KEY_ALIAS=your alias
KEY_PASSWORD=your password
接下在guild.gradle檔案中讀取signing.properties配置檔案,讀取的程式碼如下:
File propFile = file('signing.properties');
if (propFile.exists()) {
def Properties props = new Properties()
props.load(new FileInputStream(propFile))
if (props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') &&
props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) {
android.signingConfigs.release.storeFile = file(props['STORE_FILE'])
android.signingConfigs.release.storePassword = props['STORE_PASSWORD']
android.signingConfigs.release.keyAlias = props['KEY_ALIAS']
android.signingConfigs.release.keyPassword = props['KEY_PASSWORD']
} else {
android.buildTypes.release.signingConfig = null
}
} else {
android.buildTypes.release.signingConfig = null
}
我們還可以在gradle中配置我們打出包的包名:
在buildTypes{}中新增如下程式碼:
android.applicationVariants.all { variant ->
// each遍歷variant
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null) {
println "======outputFile.name======" + outputFile.name;
def fileName;
if (outputFile.name.endsWith('app-demo1-release.apk')) {
fileName="demo1-AndroidTrader-${defaultConfig.versionName}.apk" //打出包的包名
}else if(outputFile.name.endsWith('app-demo2-release.apk')){
fileName="demo2-AndroidTrader-${defaultConfig.versionName}.apk"
} else {
fileName='app-release.apk';
}
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
接下來,我們可以使用gradle進行打包gradle assembleRelease // 構建productFlavors下所有Variant Release版本
gradle assembleDebug // 構建productFlavors下所有Variant Debug版本
gradle assemble[productFlavors.name] // 構建productFlavors下name的Variant Release和Debug版本
gradle assemble[productFlavors.name]Relase // 構建productFlavors下name的Variant Releaseg版本
gradle assemble[productFlavors.name]Debug // 構建productFlavors下name的Variant Debug版本
也可以通過AS進行編譯打包