最近開始養成了寫博客的習慣。。。。希望後續能寫出更高質量的文章。。
由於工作項目的需要,我往往需要一份代碼>多份資源>多個app。
然而每個app都有自己的包名,id,微信id…等等一系列的參數,這些參數 有的需要寫在中 有的需要寫在代碼內,寫在String.xml中又增加了不安全的因素,導致非常難封裝到一個文件內,加上當年用Eclipse工具開發,修改包名都要兩分鐘,編譯也非常慢,有時甚至會卡死掉,真是蛋疼死了。
自從Android studio正式被推出,附帶了Gradle這強大的東西,感覺從原始社會一下穿越到了現代。
說着說着 扯遠了,簡單寫一下我在使用Gradle構建Android項目時的一些記錄或者也可以稱其爲筆記的一些東西:
gradle可以定義res文件、方法函數、配置參數,並且可在 .class文件、Manifest文件以及gradle自身 中被直接調用。
自定義配置
支持定義BuildConfig值和res的值
- 配置:可以在節點 defaultConfig、buildType、productFlavors 中配置:
defaultConfig {
applicationId "wenld.moon.color"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName 1.0
resValue "string", "main_title", "name" // 代碼內調用方式: R.string maintitle
buildConfigField "boolean", "IS_LOG", "true" // 代碼內調用方式: BuildConfig.IS_LOG
}
buildTypes {
release {
resValue "string", "main_title", "name"
buildConfigField "boolean", "IS_LOG", "true"
signingConfig signingConfigs.release
}
}
productFlavors {
miui {
resValue "string", "main_title", "name"
buildConfigField "boolean", "IS_LOG", "true"
}
wandoujia {
resValue "string", "main_title", "name"
buildConfigField "boolean", "IS_LOG", "true"
}
}
- 調用:在代碼中通過 BuildConfig.IS_LOG 和 R.string.main_title 調用即可。
Manifest文件內容佔位符
對Manifest進行自定義配置,使用方法:
- 在Manifest文件中定義一個佔位符,比如以信鴿推送的Id 例子爲例,${XG_V2_ACCESS_ID},這種格式.
- 在gradle配置文件中加替換,可以在節點 defaultConfig、buildType、productFlavors 中配置,比如:
defaultConfig {
applicationId "wenld.moon.color"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName 1.0
manifestPlaceholders = [XG_V2_ACCESS_ID: "ecs23grg652"]
}
buildTypes {
release {
manifestPlaceholders = [XG_V2_ACCESS_ID: "ecs23grg652"]
signingConfig signingConfigs.release
}
}
productFlavors {
miui {
manifestPlaceholders = [XG_V2_ACCESS_ID: "ecs23grg652"]
}
wandoujia {
manifestPlaceholders = [XG_V2_ACCESS_ID: "ecs23grg652"]
}
}
同時,還可以直接在Manifest文件中用於包名的替換,直接使用${XG_V2_ACCESS_ID}即可。
定義函數
- 配置:如下
def packageTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
- 調用: ${packageTime()} 返回值: “2016-03-03”
自定義配置雖然簡單,但是功能很強大,可以擴展很多不同的應用場景,比如可以定義測試和正式版本的信鴿推送的ID以及多渠道打包等等,就不一一列舉了,自己去嘗試擴展成自己的場景吧。
簽名部分
gradle本身直接支持簽名,只需要在releas部分添加以下代碼即可
signingConfigs {
debug {
}
release {
storeFile file("../yourapp.keystore")
storePassword "your password"
keyAlias "your alias"
keyPassword "your password"
}
}
buildTypes {
debug {
minifyEnabled false
zipAlignEnabled false
shrinkResources false
signingConfig signingConfigs.debug
}
release {
minifyEnabled true//混淆編譯
zipAlignEnabled true
//移除無用的資源文件
shrinkResources true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
一般填上上面的代碼即可執行簽名,但是一般這種方式不太安全,一般建議不要在build.gradle文件中寫上簽名文件的密碼,這是由於build.gradle文件一般都會集成到代碼的版本控制中,這樣所有人都會有簽名文件的密碼,會有後續的麻煩。
可參考:Gradle構建項目時,將敏感信息保存在build.gradle之外
最終
上面說明了一下 如何在gradle中自定義配置參數、調用方法和如何gradle引入外部文件Gradle構建項目時,將敏感信息保存在build.gradle之外。
獻上完整配置:
- version.properties:
VERSION_CODE=1
VERSION_NAME=1.0
APPLICTION_ID=wenld.moon.color
APP_NAME="xiaojiaDoctor"
XG_V2_ACCESS_ID=sddffa8293d
storefile=Keystore_MH.keystore
keyAlias=MH
KEYSTORE_PASSWORD=password123
KEY_PASSWORD=password789
- builde.gradle:
apply plugin: 'com.android.application'
def packageTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
def versionPropsFile = file("version.properties")//引入文件
Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))//讀取文件
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId versionProps['APPLICTION_ID'].toString()//取出參數
minSdkVersion 14
targetSdkVersion 23
versionCode versionProps['VERSION_CODE'].toInteger()
versionName versionProps['VERSION_NAME'].toString()
resValue "string", "app_name", (new String(versionProps['APP_NAME'].toString().getBytes("ISO-8859-1"), "UTF-8"))
manifestPlaceholders = [
XG_V2_ACCESS_ID: versionProps['XG_V2_ACCESS_ID'].toString()] //
}
signingConfigs { //簽名配置
release {
storeFile file(versionProps['storefile'].toString())
storePassword versionProps['KEYSTORE_PASSWORD'].toString()
keyAlias versionProps['keyAlias'].toString()
keyPassword versionProps['KEY_PASSWORD'].toString()
}
debug {
}
}
buildTypes {
release {
minifyEnabled false//混淆編譯
shrinkResources true //移除無用的資源文件
zipAlignEnabled true //是否zip對齊
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
resValue "string", "main_title", "name" // 代碼內調用方式: R.string maintitle
}
debug {
minifyEnabled false
shrinkResources true
zipAlignEnabled true
resValue "string", "main_title", "debug_Name" //調試版本的標題
}
}
//修改生成的最終文件名
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名稱爲app_v1.0_2016-03-03.apk
fileName = "${defaultConfig.applicationId}_v${defaultConfig.versionName}_${packageTime()}}.apk"
} else {
fileName = "${defaultConfig.applicationId}_v${defaultConfig.versionName}_${packageTime()}_beta.apk"
}
output.outputFile = new File(outputDirectory, fileName)
}
}
}
productFlavors {
miui {
}
wandoujia {
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']
}
這樣我們就可以 配置多個 .properties。在budle.gradle中調用以下代碼即可生成不同的apk。
def versionPropsFile = file("version.properties")
推薦:
- 解決方法數超65536限制
- 多渠道打包插件:http://www.open-open.com/lib/view/open1438668666911.html
- gradle 增量編譯:http://www.lxway.com/572786.html
參考: