zoukankan      html  css  js  c++  java
  • android 多渠道脚本

    原创内容,转载请注明出处

    背景

    多渠道打包这个本没啥难度,但是按照官方的做法一般都要重新编译 apk, 当 apk 很大的时候,会非常耗时,美团已经提供了一种解决思路,请点击这里查看美图的思路, 之前有个群里的同学想让我将他写的 python 代码改成 shell,  好久没写 shell 也想增加点熟练度,所以便欣然同意了。

    功能

    将工作目录下指定的 apk 文件夹中的 apk 进行复制,然后在新的 apk 的 meta-info 目录下创建一个空的文件,这个文件以 channel.txt 中指定的渠道命名

    代码

    shell脚本实现

    
    

    # !/usr/bin/bash

      model=$1

    channel_file=$2
    # 空文件 便于写入此空文件到apk包中作为channel文件
    src_empty_file='czt.txt'
    # 创建一个空文件(不存在则创建)
    if [ -e $src_empty_file ]; then
        rm -i $src_empty_file
    fi
    
    touch $src_empty_file
    
    if [ ! $? -eq 0 ]; then
       exit 1;
    fi
    
    # 获取当前目录中所有的apk源包
    src_apks=()
    if [ "$model" = "" ];then
      file_path="."
    else   file_path
    ="./$model"
    fi
    for file in $(cd $file_path ; ls); do
    file=${file_path}$file
    if [ -f $file ];then basename $file | grep '.apk$' && src_apks=("${src_apks[@]}" "$file") fi done # 获取渠道列表 if [ "$channel_file" = "" ];then channel_file='channel.txt' fi f=$(cat $channel_file) function copy(){ if [ ! -e $1 ];then return 1 fi cp $1 $2 } for src_apk in ${src_apks[@]};do # file name (with extension) src_apk_file_name=$(basename $src_apk) # 分割文件名与后缀 src_apk_name=${src_apk_file_name%.apk} # 后缀名,包含. 例如: ".apk " src_apk_extension=${src_apk_file_name##*.} # 创建生成目录,与文件名相关 output_dir='output-'${src_apk_name}/ if [ -e $output_dir ]; then rm -r $output_dir fi mkdir -p $output_dir # 遍历渠道号并创建对应渠道号的apk文件 for line in $f;do target_channel=$line target_apk=${output_dir}${src_apk_name}-${target_channel}${src_apk_extension} echo "${output_dir}=======>${src_apk_name}=======>, ${target_channel} =======>, ${src_apk_extension} =======>" # 拷贝建立新apk cp $src_apk $target_apk # 初始化渠道信息 empty_channel_file="META-INF/cztchannel_${target_channel}" # 写入渠道信息 if [ ! -e $(dirname $empty_channel_file) ]; then mkdir -p $(dirname $empty_channel_file) fi touch $empty_channel_file jar -uvf $target_apk -C . $empty_channel_file done done

     python 脚本实现

    # !/usr/bin/env python3
    
    #  -*- encoding:utf-8 -*-
    
    import os
    import sys
    import zipfile
    '''
       多渠道打包
    '''
    
    dir_path = "./"
    
    channel_path = "channel.txt"
    
    apk_files = []
    channels = []
    ext = ["apk", ]
    
    class Usage(object):
        info = [];
        def __init__(self, *args, **kw):
            pass
    
        @staticmethod
        def print():
            pass
    
    
    class Shift(object):
        def __init__(self, *args, **kw):
            if 'argvs' in kw:
                self.argvs = kw['argvs']
            else:
                self.argvs = sys.argv[:]
    
    
        def __call__(self, *args, **kwargs):
            if self.argvs:
                return self.argvs.pop(0)
            else:
                return None
    
    def getApkFiles():
        apk_files = []
        for file in os.listdir(dir_path):
            if os.path.splitext(file)[1][1:] in ext:
                apk_files.append(os.path.join(dir_path, file))
        return apk_files
    
    
    def getChannels():
        channels = []
        with open(channel_path, 'r') as f:
            channels = f.readlines()
    
        return channels
    
    
    
    def params():
        global dir_path
    
        global channel_path
    
        global apk_files
        global channels
    
        if len(sys.argv) != 1:
            shift = Shift(sys.argv[1:])
            p = shift()
            if p:
                dir_path = p
    
            p = shift()
            if p:
                channel_path = p
    
        apk_files = getApkFiles()
    
        channels = getChannels()
    
    def copy(oldfile, newfile):
        if os.path.exists(newfile):
            os.remove(newfile)
        with open(oldfile, 'rb') as f:
            data = f.read()
            with open(newfile, 'wb') as f1:
                f1.write(data)
    
    
    def main():
        import shutil
        temp_channel_path = './temp_channel.txt'
        with open(temp_channel_path, 'w') as f:
            pass
    
        for apk_file in apk_files:
            apk_file_name = os.path.splitext(os.path.basename(apk_file))[0]
            out_apk = 'output_%s' % apk_file_name
            out_abs_path = os.path.join(dir_path, out_apk)
            if os.path.exists(out_abs_path):
                shutil.rmtree(out_abs_path)
            os.mkdir(out_abs_path)
            for channel in channels:
                target_apk = os.path.join(out_abs_path, 'out_%s_%s.apk' % (channel.strip(), apk_file_name.strip()))
                copy(apk_file, target_apk)
                zipped = zipfile.ZipFile(target_apk, 'a', zipfile.ZIP_DEFLATED)
                zipped.write(temp_channel_path, '%s/czt_channel_%s' % ('META-INF', channel))
                zipped.close()
        os.remove(temp_channel_path)
    
    
    
    if __name__ == '__main__':
        params()
        main()

     后记

    目前的 v1 签名机制下,对 meta-info 下的修改不会影响到 apk 签名,但是在 Android 7.0 后提供了 v2 的签名机制,这时候需要重新开发注入机制了,详细请点我

  • 相关阅读:
    初识echarts
    深浅拷贝的理解
    react基本语法及组件
    webpack使用
    网上面试资料整理
    封装原生promise函数
    vue路由懒加载及组件懒加载
    译文---C#堆VS栈(Part Four)
    译文---C#堆VS栈(Part Three)
    译文---C#堆VS栈(Part Two)
  • 原文地址:https://www.cnblogs.com/zhangyan-2015/p/6544261.html
Copyright © 2011-2022 走看看