一、關於美團多渠道打包
在Android開發中,肯定少不了要打多渠道包。Umeng有提供一些多渠道打包的方式,但是太慢了,每個渠道都要重複的去打,如果有50多個渠道,就需要編譯50乘以1個包編譯的時間。So,肯定是不可能這樣乾的,這個方案只適合一些渠道比較少的。所以我的專案裡採用的美團的多渠道打包的方式。
具體的可以移動至我的另一篇文章:Android美團多渠道打包Walle整合
二、為什麼又新寫了這一篇文章?
就如標題所示,本來萬事大吉了,可以一鍵生成多渠道包。**可是等到釋出的時候測試和我說,渠道資訊沒有了,What???**然後網上各種翻資料,去Walle專案看看有沒有類似的問題。不出所料,Walle官網也給出了原因和具體的解決方案。
可是這個方案,太蛋疼了哥。我每次都要手動的打Release包,然後上傳360加固,下載加固包。然後本地跑一次Phtyon指令碼生成渠道包。請告訴我這個操作蛋疼不?
有沒有啥辦法可以在Android Studio裡也一鍵生成多渠道包並且渠道資訊也不會丟失呢?當然是有的,自己動手豐衣足食。
把上述這些步驟全部寫在一個Gradle指令碼里,主模組Gradle apply自己的寫的指令碼。
三、自定義360加固+Walle打包指令碼
1、首先在工程主模組新建reinforce.gradle指令碼
2、複製加固資料夾到專案根目錄
(1)配置加固資料夾 把從360加固官網下載的window下載(MAC環境就MAC下載)裡的內容有個jiagu資料夾,複製到工程目錄,並且改名為reinforce,這裡隨意我是這樣命名的。然後把美團的walle-cli-all.jar複製到reinforce資料夾裡lib資料夾下。
(2)配置渠道資訊 在reinforce資料夾下新增channel.txt檔案。錄入你想要的渠道的資訊baidu #百度
xiaomi # 小米
anzhi # 安智
meizu # 魅族
vivo # vivo
oppo # oppo
huawei # 華為
sougou # 搜狗
samsung # 三星
lianxiang # 聯想
jinli # 金立
taobao #淘寶
yingyongbao #應用寶
360 #360
anzhi #安智
guanwang #官網
複製程式碼
或者直接下我弄好的:(Window) 連結: pan.baidu.com/s/1jw_0Wya4… 提取碼: igx9
3、reinforce.gradle指令碼內容如下,ext寫入專案相關的一些資訊。其他的應該都不用動。
(1) Window下的指令碼
ext {
//加固外掛路徑
reinforce_plugin_path = '../reinforce'
//360加固賬號密碼
reinforce_plugin_name = 'XXXXX'
reinforce_plugin_passward = 'XXXXXX'
//簽名資訊
key_store_path = './xyz.keystore'
key_store_passward = 'XXXXX'
alias = 'XXXXXX'
alias_passward = 'XXXXX'
//加固ApK輸出路徑
reinforce_apk_path = 'build/outputs/apk/release/reinforce/'
//加固包名稱
reinforce_apk_name = 'build/outputs/apk/release/reinforce/release_encrypted_aligned_signed.apk'
//渠道配置檔案
chanel_config_path = reinforce_plugin_path + '/channel.txt'
//渠道Apk輸出路徑
channel_apks_path = 'build/outputs/apk/release/channels/'
}
/**
* 註釋:編譯加固渠道包
* 時間:2019/1/2 0002 14:01
* 作者:郭翰林
*/
task buildReinforceRelease() {
group '360reinforce'
dependsOn('assembleRelease')
doLast {
//第一步:清空快取
cleanFilesPath(reinforce_plugin_path + "/.cache")
cleanFilesPath(reinforce_plugin_path + "/output")
cleanFilesPath(reinforce_plugin_path + "/jiagu.db")
cleanFilesPath(reinforce_apk_path)
cleanFilesPath(channel_apks_path)
//第二步:開始加固
reinforceApk()
//第三部:重新命名加固包
renameReinforceApk()
//第四步:打多渠道包
buildChannelApks()
}
}
/**
* 註釋:打多渠道包
* 時間:2019/1/4 0004 13:26
* 作者:郭翰林
*/
def buildChannelApks() {
println('開始編譯多渠道包')
File reinforceApk = new File(reinforce_apk_name)
if (!reinforceApk.exists()) {
return
}
//新建渠道包目錄
File channelsPath = new File(channel_apks_path)
if (!channelsPath.exists()) {
channelsPath.mkdir()
}
exec {
commandLine "powershell", "java -jar", reinforce_plugin_path + "/lib/walle-cli-all.jar batch -f ", chanel_config_path, reinforce_apk_name, channel_apks_path
}
println('編譯多渠道包成功,生成的渠道包路徑:' + channelsPath.getAbsolutePath())
}
/**
* 註釋:重新命名已加固好的APK
* 時間:2019/1/4 0004 12:48
* 作者:郭翰林
*/
def renameReinforceApk() {
File files = new File('build/outputs/apk/release/reinforce')
if (!files.exists()) {
return
}
if (files.isDirectory()) {
String[] content = files.list()//取得當前目錄下所有檔案和資料夾
for (String name : content) {
//由於第一步清空快取,reinforce資料夾內只會有一個已經加固並且簽名的包
File signedApk = new File('build/outputs/apk/release/reinforce', name)
File renameApk = new File(reinforce_apk_name)
if (signedApk.exists() && signedApk.isFile()) {
signedApk.renameTo(renameApk)
}
}
}
}
/**
* 註釋:使用360加固加固Release包
* 時間:2019/1/2 0002 14:32
* 作者:郭翰林
*/
def reinforceApk() {
println('開始進行加固操作')
File releaseApk = new File('build/outputs/apk/release/app-release.apk')
if (!releaseApk.exists()) {
throw new FileNotFoundException('Release包不存在,無法進行加固操作')
}
String releasePath = 'build/outputs/apk/release/app-release.apk'
//建立加固資料夾
File reinforcePath = new File(reinforce_apk_path)
if (!reinforcePath.exists()) {
reinforcePath.mkdir()
}
exec {
commandLine "powershell", "java -jar", reinforce_plugin_path + "/jiagu.jar", "-login", reinforce_plugin_name, reinforce_plugin_passward
}
exec {
commandLine "powershell", "java -jar", reinforce_plugin_path + "/jiagu.jar", "-importsign", key_store_path, key_store_passward, alias, alias_passward
}
exec {
commandLine "powershell", "java -jar", reinforce_plugin_path + "/jiagu.jar", "-jiagu", releasePath, reinforce_apk_path, "-autosign"
}
println('加固操作結束,加固包路徑' + reinforcePath.getAbsolutePath())
}
/**
* 註釋:清空資料夾
* 時間:2019/1/2 0002 14:15
* 作者:郭翰林
*/
def cleanFilesPath(String path) {
File files = new File(path)
if (!files.exists()) {
return
}
println('開始執行清除:' + files.getAbsolutePath())
if (files.isDirectory()) {
String[] content = files.list()//取得當前目錄下所有檔案和資料夾
for (String name : content) {
File temp = new File(path, name)
if (temp.isDirectory()) {//判斷是否是目錄
cleanFilesPath(temp.getAbsolutePath())//遞迴呼叫,刪除目錄裡的內容
temp.delete()
} else {
temp.delete()
}
}
}
files.delete()
}
複製程式碼
(2)MAC環境下指令碼
ext {
//加固外掛路徑
reinforce_plugin_path = "${project.rootDir}/reinforce"
reinforce_plugin_name = 'xxxxxx'
reinforce_plugin_passward = 'xxxxxxx'
//簽名資訊
key_store_path = "${project.rootDir}/app/xyz.keystore"
key_store_passward = 'xxxxxxx'
alias = 'xxxxx'
alias_passward = 'xxxxxxxx'
//Release Apk輸出路勁
release_apk_path = "${project.buildDir}/outputs/apk/release/app-release.apk"
//加固ApK輸出路徑
reinforce_apk_path = "${project.buildDir}/outputs/apk/release/reinforce/"
//加固包名稱
reinforce_apk_name = "${project.buildDir}/outputs/apk/release/reinforce/release_encrypted_aligned_signed.apk"
//渠道配置檔案
chanel_config_path = "${reinforce_plugin_path}/channel.txt"
//渠道Apk輸出路徑
channel_apks_path = "${project.buildDir}/outputs/apk/release/channels/"
}
/**
* 註釋:編譯加固渠道包
* 時間:2019/1/2 0002 14:01
* 作者:郭翰林
*/
task buildReinforceRelease() {
group '360reinforce'
dependsOn('assembleRelease')
doLast {
//第一步:清空快取
cleanFilesPath(reinforce_plugin_path + "/.cache")
cleanFilesPath(reinforce_plugin_path + "/output")
cleanFilesPath(reinforce_plugin_path + "/jiagu.db")
cleanFilesPath(reinforce_apk_path)
cleanFilesPath(channel_apks_path)
//第二步:開始加固
reinforceApk()
//第三部:重新命名加固包
renameReinforceApk()
//第四步:打多渠道包
buildChannelApks()
//清除無用快取
cleanFilesPath(reinforce_plugin_path + "/.cache")
cleanFilesPath(reinforce_plugin_path + "/output")
cleanFilesPath(reinforce_plugin_path + "/jiagu.db")
}
}
/**
* 註釋:打多渠道包
* 時間:2019/1/4 0004 13:26
* 作者:郭翰林
*/
def buildChannelApks() {
println('開始編譯多渠道包')
File reinforceApk = new File(reinforce_apk_name)
if (!reinforceApk.exists()) {
return
}
//新建渠道包目錄
File channelsPath = new File(channel_apks_path)
if (!channelsPath.exists()) {
channelsPath.mkdir()
}
exec {
commandLine "bash", "-c", "java -jar ${reinforce_plugin_path}/lib/walle-cli-all.jar batch -f ${chanel_config_path} ${reinforce_apk_name} ${channel_apks_path}"
}
println('編譯多渠道包成功,生成的渠道包路徑:' + channelsPath.getAbsolutePath())
}
/**
* 註釋:重新命名已加固好的APK
* 時間:2019/1/4 0004 12:48
* 作者:郭翰林
*/
def renameReinforceApk() {
File files = new File(reinforce_apk_path)
if (!files.exists()) {
return
}
if (files.isDirectory()) {
String[] content = files.list()//取得當前目錄下所有檔案和資料夾
for (String name : content) {
//由於第一步清空快取,reinforce資料夾內只會有一個已經加固並且簽名的包
File signedApk = new File(reinforce_apk_path, name)
File renameApk = new File(reinforce_apk_name)
if (signedApk.exists() && signedApk.isFile()) {
signedApk.renameTo(renameApk)
}
}
}
}
/**
* 註釋:使用360加固加固Release包
* 時間:2019/1/2 0002 14:32
* 作者:郭翰林
*/
def reinforceApk() {
println('開始進行加固操作')
File releaseApk = new File(release_apk_path)
if (!releaseApk.exists()) {
throw new FileNotFoundException("Release包不存在,無法進行加固操作,檔案路徑:${releaseApk.getAbsolutePath()}")
}
//建立加固資料夾
File reinforcePath = new File(reinforce_apk_path)
if (!reinforcePath.exists()) {
reinforcePath.mkdir()
}
exec {
commandLine "bash", "-c", "chmod +x ${reinforce_plugin_path}/java/bin/*"
}
exec {
commandLine "bash", "-c", "java -jar ${reinforce_plugin_path}/jiagu.jar -login ${reinforce_plugin_name} ${reinforce_plugin_passward}"
}
exec {
commandLine "bash", "-c", "java -jar ${reinforce_plugin_path}/jiagu.jar -importsign ${key_store_path} ${key_store_passward} ${alias} ${alias_passward}"
}
exec {
commandLine "bash", "-c", "java -jar ${reinforce_plugin_path}/jiagu.jar -jiagu ${release_apk_path} ${reinforce_apk_path} -autosign"
}
println('加固操作結束,加固包路徑' + reinforcePath.getAbsolutePath())
}
/**
* 註釋:清空資料夾
* 時間:2019/1/2 0002 14:15
* 作者:郭翰林
*/
def cleanFilesPath(String path) {
File files = new File(path)
if (!files.exists()) {
return
}
println('開始執行清除:' + files.getAbsolutePath())
if (files.isDirectory()) {
String[] content = files.list()//取得當前目錄下所有檔案和資料夾
for (String name : content) {
File temp = new File(path, name)
if (temp.isDirectory()) {//判斷是否是目錄
cleanFilesPath(temp.getAbsolutePath())//遞迴呼叫,刪除目錄裡的內容
temp.delete()
} else {
temp.delete()
}
}
}
files.delete()
}
複製程式碼
四、整合完畢之後,如何使用
1、查詢名為buildReinforceRelease的Task任務 2、待生成完畢之後,渠道包在主模組下的build/outputs/apk/release/channels/資料夾下