Android分渠道打包(Python 3.4 实现)
Android批量打包实现有很多方式你可以用Ant,Maven或者Gradle。在处理多个Library和NDK编译的时候配置有些麻烦,且每个渠道都编译一次效率较低。如果没有复杂的分渠道编译需求,我们可以换种简单的方式。因为apk中的assets是不会编译的,我们可以修改assets文件的值实现渠道修改,这样你的apk就可以通过读取修改过的文件区分各个渠道,用于数据统计。下面是我写的一个python脚本:
使用说明(Python 3.4):
1. 使用IDE工具导出未签名Apk,apk文件为WMShua.apk 2. 将APK放到脚本同级目录 3. 将签名文件放到同级目录下 4. 执行该脚本进行签名,可指定参数修改默认值
5. -h 查看帮助
#!/usr/bin/env python # encoding: utf-8 import zipfile import os import shutil import subprocess import sys keystore = <默认签名文件名 例如 "example.keystore"> storepass = <默认签名文件秘钥 例如 "example"> keypass = <默认秘钥 例如 "example"> alias = <默认签名文件别名 alias 例如 "www.example.com"> unsigned_apk_file = <默认未签名APK 例如 "example.apk"> apk_prefix = <默认签名APK名称前缀 例如 "_prefix"> apk_postfix = <默认签名APK名称后缀 例如 "_post"> base_extractPath = <默认临时导出目录 例如 "_output"> version_flag = <默认版本全称 例如 "_beta_1.0.1"> channel_file = <默认渠道文件相对路径 例如 "assets/channel_id"> channels = { '1000': "官网", '1001': "91", '1002': "百度", '1003': "安卓", '1004': "豌豆荚", '1005': "应用宝", '1006': "360", '1007': "应用汇", '1008': "魅族", '1009': "N多网", '1010': "PP助手", '1011': "淘宝", '1012': "机锋网", '1013': "金立", '1014': "小米", '1015': "华为", '1016': "搜狗", '1017': "安智", '1018': "沃商店", '1019': "itools", '1020': "电信爱游戏", '1021': "优亿市场", '1022': "应用贝", '1023': "googleplay", '1024': "安粉网" } def extract(zfile, path): z = zipfile.ZipFile(zfile,'r') for filename in z.namelist(): if not filename.endswith('/'): f = os.path.join(path, filename) dir = os.path.dirname(f) if not os.path.exists(dir): os.makedirs(dir) singleFile = open(f, "wb") singleFile.write(z.read(filename)) z.close() def modifyChannel(path, channel_id): m_file = open(os.path.join(path, channel_file), "w") m_file.write(channel_id) m_file.flush() m_file.close() print("---------modifyChannel-----------") def obtainFileListInfolder(path): filelist = [] if os.path.isfile(path): filelist.append(path) else : for root, dirs, files in os.walk(path): for name in files: filelist.append(os.path.join(root, name)) return filelist def reArchive(path, zipfilename): filelist = obtainFileListInfolder(path) zf = zipfile.ZipFile(zipfilename, "w", zipfile.zlib.DEFLATED) for tar in filelist: arcname = tar[len(path):] #print arcname zf.write(tar, arcname) zf.close() def signApk(src, target): signedCmd = "jarsigner -verbose -keystore " + keystore + " -storepass " + storepass +" -keypass "+ keypass +" -signedjar " + target + " " + src + " " + alias print("---------signApk-----------" + signedCmd) subprocess.call(signedCmd) print("--------------------signedApk:" + target) def clearTmpFiles(paths): for path in paths: if os.path.exists(path): if os.path.isfile(path): os.remove(path) else: shutil.rmtree(path) def handleArgv(argv): for i in range(1, len(argv)): if len(argv) > i + 1 and '-h' != argv[i]: if '-v' == argv[i] : version_flag = argv[i + 1] elif '-u' == argv[i] : unsigned_apk_file = argv[i + 1] elif '-K' == argv[i] : keystore = argv[i + 1] elif '-s' == argv[i] : storepass = argv[i + 1] elif '-k' == argv[i]: keypass = argv[i + 1] elif '-b' == argv[i]: apk_prefix = argv[i + 1] elif '-e' == argv[i]: apk_postfix = argv[i + 1] elif '-c' == argv[i]: channel_file = argv[i + 1] return False elif '-h' == argv[i]: helpstr = '''\n使用说明(Python 3.4):\n 1. 使用IDE工具导出未签名Apk,apk文件为WMShua.apk\n 2. 将APK放到脚本同级目录\n 3. 将签名文件放到同级目录下\n 4. 执行该脚本进行签名,可指定参数修改默认值,参数如下:\n''' helpstr += ''' -v version_flag 版本全称 -u unsigned_apk_file 未签名Apk -K keystore 秘钥文件 -k keypass 秘钥 -s storepass 文件秘钥 -b apk_prefix 签名文件前缀 -e apk_postfix 签名文件后缀 -c channel_file 需要修改的渠道文件相对路径 -h help''' print(helpstr) return True else: print("参数未指定,使用默认参数!") return False if __name__ == "__main__": isJusthelp = False if sys.argv and len(sys.argv) >= 2: isJusthelp = handleArgv(sys.argv) if not isJusthelp: for channel_id in channels: print('--------------------------------'+ channels[channel_id] + '('+ channel_id + ')'+'-----------------------------------') channel_apk = channel_id +"_"+ channels[channel_id] + apk_prefix + ".apk" signed_channel_apk = channel_id +"_"+ channels[channel_id] + apk_prefix + version_flag + apk_postfix totalExtractPath = base_extractPath + channel_id print("---------------开始解压缩:" + totalExtractPath) extract(unsigned_apk_file, totalExtractPath) print("---------------修改渠道:" + channel_id) modifyChannel(totalExtractPath, channel_id) print("---------------重新打包:" + channel_apk) reArchive(totalExtractPath, channel_apk) print("---------------签名:" + signed_channel_apk) signApk(channel_apk, signed_channel_apk) print("---------------清除临时文件...") paths = [totalExtractPath, channel_apk] ### 清除临时文件 clearTmpFiles(paths) print('------------------------分渠道打包完成-------------------------')