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('------------------------分渠道打包完成-------------------------')

 

你可能感兴趣的:(Android分渠道打包(Python 3.4 实现))