寫在前面的話
公司之前使用Ant打包的,一個(gè)包平均要10分鐘堕战,三四個(gè)包下來,一個(gè)小時(shí)過去了拍霜,作為一名有追求的程序員嘱丢,這是不能忍受的,所以老大安排我對(duì)打包腳本進(jìn)行改造祠饺。
本次改造包括以下內(nèi)容:
- 編譯器由IDEA向AndroidStudio轉(zhuǎn)換
- 增加多渠道打包
- 修改打包后的apk文件名
- 備份混淆后的mapping文件
接下來就按照這幾塊來細(xì)說一下多渠道打包的事
編譯器由IDEA向AndroidStudio轉(zhuǎn)換
公司的項(xiàng)目原本是在IDEA上開發(fā)的屿讽,這款軟件是后臺(tái)開發(fā)的神器,AS在其基礎(chǔ)上增加了一些新功能吠裆。編譯的管理也不是Gradle伐谈,所以老大想轉(zhuǎn)到AS開發(fā),然后用Gradle试疙。
在轉(zhuǎn)的過程中也遇到了一些問題诵棵。總結(jié)來說這些問題可以分為:分包祝旷,多個(gè)jar包重復(fù)引用履澳,低版本Android support包缺少一些方法嘶窄,uses-sdk的兼容問題。我把異常信息貼上來就行了,本文重點(diǎn)不在這里距贷。
多jar重復(fù)引用
Error:Execution failed for task ':_2C:transformClassesWithJarMergingForRelease'.
> com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: io/agora/rtc/IRtcEngineEventHandler$AudioVolumeInfo.class
分包
Error:Execution failed for task ':_2C:transformClassesWithDexForRelease'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
版本過低柄冲,缺少方法
Error:(263, 22) 錯(cuò)誤: 找不到符號(hào)
符號(hào): 方法 addDrawerListener(Main)
位置: 類型為DrawerLayout的變量 mDrawerLayout
將依賴的minSdkVersion改為與項(xiàng)目一致
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="22"
tools:overrideLibrary="org.ffmpeg.android,android.support.v7.recyclerview,android.support.coreui,
android.support.compat,android.support.v4,android.support.fragment,android.support.mediacompat,
android.support.coreutils,android.support.v13"/>
增加多渠道打包
除了要增加多渠道打包外,還需要在多渠道中修改一些東西忠蝗,具體修改的內(nèi)容如下:
1现横、首先不同的應(yīng)用需要修改applicationId(百度地圖,友盟統(tǒng)計(jì)阁最,訊飛語音的App_key)
2戒祠、用到shareSDK,不同的渠道要替換現(xiàn)在assets這個(gè)目錄下面的文件。
3速种、不同的應(yīng)用的圖標(biāo)替換
4姜盈、應(yīng)用數(shù)據(jù)的SD卡存儲(chǔ)目錄
5、應(yīng)用的AAS接口地址
6配阵、修改生成的apk名字和備份mapping 文件
1 修改applicationId 馏颂。修改友盟,微信等第三方App_Key等動(dòng)態(tài)數(shù)據(jù)都是通過 manifestPlaceholders 占位符的形式進(jìn)行修改 貼一下圖看一下就懂了
不同的渠道有不同的applicationId,然后修改應(yīng)用的名字棋傍,App_Key PERMISSION這個(gè)字段是由于項(xiàng)目中用到了自定義權(quán)限救拉,所以要根據(jù)applicationId進(jìn)行修改。到此舍沙,第一步完成了,是不是很快剔宪?
2 用到shareSDK,不同的應(yīng)用要替換現(xiàn)在assets這個(gè)目錄下面的文件拂铡。
3 不同的應(yīng)用的圖標(biāo)替換
處理這個(gè)問題實(shí)質(zhì)就是資源文件的替換(包括assets 和res 文件的合并)
多說無益,看圖把
這里我用了相對(duì)路徑葱绒,相對(duì)于App項(xiàng)目感帅,這樣子提交到svn的話就不用修改路徑了。通過為每一個(gè)渠道指定assets和res的目錄達(dá)到編譯的時(shí)候動(dòng)態(tài)合并資源
4 應(yīng)用數(shù)據(jù)的SD卡存儲(chǔ)目錄
5 應(yīng)用的AAS接口地址
這個(gè)項(xiàng)的要用到buildConfigField 和BuildConfig地淀,在buildConfigField的參數(shù)會(huì)在編譯的時(shí)候生成到BuildConfig中失球,每一個(gè)渠道都會(huì)生成一個(gè)BuildConfig,通過它來達(dá)到動(dòng)態(tài)修改SD卡存儲(chǔ)目錄和AAS接口地址 帮毁。
老規(guī)矩实苞,上圖
這個(gè)是在build.gradle中定義的
看看BuildConfig中的定義
說完這個(gè)后我還想說一個(gè),如何在這個(gè)BuildConfig中生成一個(gè)對(duì)象烈疚,
解決這個(gè)問題的話就想想我們平時(shí)實(shí)例化一個(gè)對(duì)象是怎么做的,包名+類 類名 = new 包名+類(),然后看看上圖黔牵,就明了。寫全路徑是為了解決導(dǎo)包的問題爷肝。
6 修改生成的apk名字和備份mapping 文件
//App同級(jí)目錄中新建一個(gè)APK文件夾
def apkUrl = file('../APK')
applicationVariants.all { variant ->
variant.outputs.each { output ->
//修改apk名字并輸出到指定位置
def fiName
if (variant.productFlavors[0].name == "internal") {
fiName = "Xiaolaba_a_build_${variant.productFlavors[0].name}_${releaseCode}.apk"
} else {
fiName = "School_a_v${defaultConfig.versionName}_${variant.productFlavors[0].name}_${releaseCode}.apk"
}
output.outputFile = new File(apkUrl, fiName)
//備份mapping文件
if (variant.getBuildType().isMinifyEnabled()) {
variant.assemble.doLast {
copy {
from variant.mappingFile
into "${rootDir}/APK"
rename { String fileName ->
"mapping-${fiName}.txt"
}
}
}
}
}
}
總結(jié)
到此猾浦,多渠道的打包就已經(jīng)完成了陆错。不過還想提一下如何令build.gradle 這個(gè)文件如何變得優(yōu)雅起來
首先,在app的build.gradle中新建一個(gè)config.gradle
其次 在build.gradle中引入config.gradle金赦,project代表當(dāng)前的build.gradle 定義好這些參數(shù)后就可以用了音瓷。
這是我在項(xiàng)目中用到的config.gradle xxxxx代表一些敏感信息,所以在這里隱去
ext {
android = [
compileSdkVersion: 23,
buildToolsVersion: "26.0.0",
minSdkVersion : 8,
targetSdkVersion : 23
]
//基礎(chǔ)配置
dependency = [
gridlayout : 'com.android.support:gridlayout-v7:23.4.0',
recyclerview: 'com.android.support:recyclerview-v7:23.4.0',
multidex : 'com.android.support:multidex:1.0.0',
gson : 'com.google.code.gson:gson:2.7',
support : 'com.android.support:support-v13:23.4.0'
]
//業(yè)務(wù)地址
urlSetting = [
ethernet_addr: "xxxxx",
dev_addr : "xxxxx",
school_addr : "xxxxx",
tyd_qdmy_addr:"xxxxx"
]
//多渠道相關(guān)
flavorsSetting = [
app_id_tyd : "xxxxx",
app_name_tyd : "xxxxx",
app_id_qdmy : "xxxxx",
app_name_qdmy : "xxxxx",
app_id_school : "xxxxx",
app_name_school : "xxxxx",
app_name_internal: "xxxxx"
]
//版本相關(guān)
def versionCode = getVersionCode(releaseTimeAndVersionCode())
def versionName = getVersionName()
versionSettting = [
versionCode: versionCode,
versionName: versionName
]
}
def releaseTimeAndVersionCode() {
String time = new Date().format("yyMMdd", TimeZone.getTimeZone("UTC"))
return time.substring(1, time.length())
}
def getVersionCode(String version) {
return Integer.parseInt(version)
}
def getVersionName() {
def versionFile = file('version.properties')
if (versionFile.exists()) {
def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionFile))
def versionCode = versionProps['versionName'].toString()
return versionCode
} else {
throw new GradleException("Could not find version.properties!")
}
}
好了夹抗,多渠道打包總結(jié)就到此結(jié)束了绳慎。有不明白的地請(qǐng)留言。