一鍵式Android打包(打包+加固+多渠道)

一.Android生成原始apk

1.通過(guò)android studio打包生成
2.通過(guò)jenkins打包生成

如果選擇第1種方式的壞處:android studio打包兵迅,再通過(guò)360加固工具加固抢韭,最后通過(guò)美團(tuán)的walle多渠道打包技術(shù),需要分成三步才能完成操作恍箭,比較繁瑣
如果選擇第2種方式的好處:通過(guò)python腳本集成到j(luò)enkins中刻恭,可通過(guò)一鍵完成所有操作,比較簡(jiǎn)潔方便

二.選擇jenkins扯夭,介紹用python腳本怎樣三步集成到一起

1.關(guān)于通過(guò)jenkins編譯生成apk鳍贾,網(wǎng)上有多文章可以借鑒,在此就不做介紹了
2.jenkins項(xiàng)目配置中找到構(gòu)建交洗,如下圖設(shè)置:


jenkins構(gòu)建.png

從上圖可以看到在step2編譯打包任務(wù)的之前增加了step1骑科,目的是為了在編譯打包之前修改想要的代碼或者其他android配置,step3是為了打包完之后對(duì)這個(gè)包進(jìn)行類(lèi)似于上傳到蒲公英平臺(tái)的操作供測(cè)試人員下載藕筋,對(duì)于正式的發(fā)布這個(gè)step3其實(shí)是可以省略的纵散,最后step4就是加固命令+美團(tuán)多渠道打包命令,最終腳本添加方式就如上圖

三.腳本代碼(重點(diǎn)隐圾!重點(diǎn)伍掀!重點(diǎn)!)

step1. pre-build.py

#coding=utf-8
from __future__ import print_function
import os
import requests
import sys
import re
import argparse
#獲取執(zhí)行命令時(shí)設(shè)置的參數(shù)值
def parse_args():
    parser = argparse.ArgumentParser(description='Pre build script.')
    #python ${WORKSPACE}/Build_scripts/pre-build.py \--workspace ${WORKSPACE}
    #如果執(zhí)行上面的語(yǔ)句暇藏,那workspace這個(gè)參數(shù)對(duì)應(yīng)的值的獲取就如下面
    parser.add_argument('--workspace', dest="workspace", default=None, help="the workspace DIR")
    args = parser.parse_args()
    return args

def main():
    args = parse_args()
    #舉例說(shuō)明 可以修改gradle.properties蜜笤、settings.gradle的參數(shù),
    #其實(shí)只要android項(xiàng)目里的都可以進(jìn)行修改盐碱,我這里修改的原因是我開(kāi)發(fā)用的是windows把兔,
    #但jenkins是放在mac的服務(wù)器中,所以會(huì)產(chǎn)生路徑的不一致瓮顽,所以在進(jìn)行編譯打包之前要進(jìn)行修改一下
    file_path = "%s/gradle.properties" % args.workspace
    with open(file_path, 'r') as f:
        text = f.read()
    with open(file_path, 'w') as f:
        f.write(text.replace('D:/xxx' , '../xxx'))

    file_path = "%s/settings.gradle" % args.workspace
    with open(file_path , 'r') as f:
        text = f.read()
    with open(file_path, 'w') as f:
        f.write(text.replace('../xxx', './xxx'))

if __name__ == '__main__':
    main()

step3. build.py正式版本可以省略--不作介紹
step4. app-singer.py 此腳本內(nèi)引用了config.py的配置腳本

import os
import sys
#這個(gè)config導(dǎo)入其實(shí)是配置文件也是自己定義的县好,
#再后面會(huì)介紹這個(gè)配置
import config 
import platform
import shutil
#獲取腳本文件的當(dāng)前路徑
def curFileDir():
     #獲取腳本路徑
     path = sys.path[0]
     #判斷為腳本文件還是py2exe編譯后的文件,
     #如果是腳本文件暖混,則返回的是腳本的目錄缕贡,
     #如果是編譯后的文件,則返回的是編譯后的文件路徑
     if os.path.isdir(path):
         return path
     elif os.path.isfile(path):
         return os.path.dirname(path)

#判斷當(dāng)前系統(tǒng)
def isWindows():
  sysstr = platform.system()
  if("Windows" in sysstr):
    return 1
  else:
    return 0

#兼容不同系統(tǒng)的路徑分隔符
def getBackslash():
    if(isWindows() == 1):
        return "\\"
    else:
        return "/"


# 清空臨時(shí)資源
def cleanTempResource():
  try:
    os.remove(protectedSourceApkPath)
    os.remove(zipalignedApkPath)
    os.remove(signedApkPath)
    pass
  except Exception:
    pass
 
 # 清空渠道信息
def cleanChannelsFiles():
  try:
    os.makedirs(channelsOutputFilePath)
    pass
  except Exception:
    pass

# 創(chuàng)建Channels輸出文件夾
def createChannelsDir():
  try:
    os.makedirs(channelsOutputFilePath)
    pass
  except Exception:
    pass

    
#當(dāng)前腳本文件所在目錄
parentPath = curFileDir() + getBackslash()

#config
libPath = parentPath + "lib" + getBackslash()
buildToolsPath =  config.sdkBuildToolPath + getBackslash()
checkAndroidV2SignaturePath = libPath + "CheckAndroidV2Signature.jar"
walleChannelWritterPath = libPath + "walle-cli-all.jar"
keystorePath = parentPath + config.keystorePath
keyAlias = config.keyAlias
keystorePassword = config.keystorePassword
keyPassword = config.keyPassword
jiaguName = config.jiaguName
jiaguPassword = config.jiaguPassword
channelsOutputFilePath = parentPath + "channels"
channelFilePath = parentPath +"channel"
protectedSourceApkPath = parentPath + config.protectedSourceApkName
jiagujarPath = config.jiagujarPath + getBackslash() + "jiagu.jar"
originReleaseApkPath = config.originReleaseApkPath

# 檢查自定義路徑拣播,并作替換
if len(config.protectedSourceApkDirPath) > 0:
  protectedSourceApkPath = config.protectedSourceApkDirPath + getBackslash() + config.protectedSourceApkName

if len(config.channelsOutputFilePath) > 0:
  channelsOutputFilePath = config.channelsOutputFilePath

if len(config.channelFilePath) > 0:
  channelFilePath = config.channelFilePath

zipalignedApkPath = protectedSourceApkPath[0 : -4] + "_aligned.apk"
signedApkPath = protectedSourceApkPath[0 : -10] + ".apk" #_signed

# 創(chuàng)建Channels輸出文件夾
createChannelsDir()

#清空Channels輸出文件夾
cleanChannelsFiles()

#360加固login
jiagu360LoginShell = "java -jar " + jiagujarPath + " -login " + jiaguName + " " + jiaguPassword ;
os.system(jiagu360LoginShell)

#360加固apk
jiagu360Shell = "java -jar " + jiagujarPath + " -jiagu " + originReleaseApkPath + " " + parentPath;
os.system(jiagu360Shell)
print(jiagu360Shell)

#對(duì)齊
zipalignShell = buildToolsPath + "zipalign -v 4 " + protectedSourceApkPath + " " + zipalignedApkPath
os.system(zipalignShell)

#簽名
signShell = buildToolsPath + "apksigner sign --ks "+ keystorePath + " --ks-key-alias " + keyAlias + " --ks-pass pass:" + keystorePassword + " --key-pass pass:" + keyPassword + " --out " + signedApkPath + " " + zipalignedApkPath
os.system(signShell)
print(signShell)

#檢查V2簽名是否正確
checkV2Shell = "java -jar " + checkAndroidV2SignaturePath + " " + signedApkPath;
os.system(checkV2Shell)

#寫(xiě)入渠道
if len(config.extraChannelFilePath) > 0:
  writeChannelShell = "java -jar " + walleChannelWritterPath + " batch2 -f " + config.extraChannelFilePath + " " + signedApkPath + " " + channelsOutputFilePath
else:
  writeChannelShell = "java -jar " + walleChannelWritterPath + " batch -f " + channelFilePath + " " + signedApkPath + " " + channelsOutputFilePath
os.system(writeChannelShell)
#清理無(wú)用的文件
cleanTempResource()

print ("\n"+channelsOutputFilePath+"\n")

config.py的配置腳本

#Windows 下路徑分割線請(qǐng)注意使用\\轉(zhuǎn)義  
#keystore信息
# xxx.keystore放在與config.py同一級(jí)別目錄
keystorePath = "xxx.keystore"
keyAlias = "xxx"
keystorePassword = "xxx"
keyPassword = "xxx"
#360jiagu賬號(hào)密碼
jiaguName="xxx"
jiaguPassword="xxx"

#app版本號(hào)
#此參數(shù)其實(shí)可以通過(guò)pre-build.py中獲取workspace的方式傳入晾咪,
#也可以通過(guò)文件的讀寫(xiě)直接去android項(xiàng)目的代碼中直接去讀取出來(lái)
appVersion = "607"
#android sudio打包的apk完整路徑
originReleaseApkPath = "C:\\Users\\xxx\\Desktop\\release\\app-release.apk"
#加固后的源文件名(未重簽名)
protectedSourceApkName = "app-release_" + appVersion + "_jiagu.apk"
#加固后的源文件所在文件夾路徑(...path),注意結(jié)尾不要帶分隔符,默認(rèn)在此文件夾根目錄
protectedSourceApkDirPath = ""
#渠道包輸出路徑贮配,默認(rèn)在此文件夾Channels目錄下
channelsOutputFilePath = ""
#渠道名配置文件路徑谍倦,默認(rèn)在此文件夾根目錄
channelFilePath = ""
#額外信息配置文件(絕對(duì)路徑,例如/Users/mac/Desktop/walle360/config.json)
#配置信息示例參看https://github.com/Meituan-Dianping/walle/blob/master/app/config.json
extraChannelFilePath = ""
#Android SDK buidtools path , please use above 25.0+
sdkBuildToolPath = "C:\\Users\\xxx\\Android\\sdk\\build-tools\\26.0.2"
#jiagu.jar的源文件路徑
jiagujarPath = "D:\\360jiagubao_windows_64\\jiagu"

最后泪勒,所有的配置方式大致這樣昼蛀,每一個(gè)步驟雖然都不是細(xì)致到手把手教的程度宴猾,但是給出了整體的思路,大家可以根據(jù)大致的步驟思路一步一步配置曹洽,慢慢采坑才能更加的理解記住

上述腳本借鑒了github的資源ProtectedApkResignerForWalle鳍置,并對(duì)腳本增加了360加固命令和一些適當(dāng)?shù)哪_本修改

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市送淆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌怕轿,老刑警劉巖偷崩,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異撞羽,居然都是意外死亡阐斜,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)诀紊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谒出,“玉大人,你說(shuō)我怎么就攤上這事邻奠◇栽” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵碌宴,是天一觀的道長(zhǎng)杀狡。 經(jīng)常有香客問(wèn)我,道長(zhǎng)贰镣,這世上最難降的妖魔是什么呜象? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮碑隆,結(jié)果婚禮上恭陡,老公的妹妹穿的比我還像新娘。我一直安慰自己上煤,他們只是感情好休玩,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著楼入,像睡著了一般哥捕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嘉熊,一...
    開(kāi)封第一講書(shū)人閱讀 52,328評(píng)論 1 310
  • 那天遥赚,我揣著相機(jī)與錄音,去河邊找鬼阐肤。 笑死凫佛,一個(gè)胖子當(dāng)著我的面吹牛讲坎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播愧薛,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼晨炕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了毫炉?” 一聲冷哼從身側(cè)響起瓮栗,我...
    開(kāi)封第一講書(shū)人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瞄勾,沒(méi)想到半個(gè)月后费奸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡进陡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年愿阐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趾疚。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缨历,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出糙麦,到底是詐尸還是另有隱情辛孵,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布喳资,位于F島的核電站觉吭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏仆邓。R本人自食惡果不足惜鲜滩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望节值。 院中可真熱鬧徙硅,春花似錦、人聲如沸搞疗。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)匿乃。三九已至桩皿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間幢炸,已是汗流浹背泄隔。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宛徊,地道東北人佛嬉。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓逻澳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親暖呕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子斜做,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容