Android 多渠道打包方案

常规Build

我们先来回顾一下通过Ant或者Gradle进行多渠道批量打包,通常是在AndroidManifest中配置:

<meta-data android:name="CHANNEL" android:value="xxx" />

meta-data通过配置value来动态改变渠道名称,然后我们可以在代码中这样去获取Channel

private String getChannelNameFromManifest(){
try {

        return (String) mContext.getPackageManager().getApplicationInfo(mContext.getPackageName(), PackageManager.GET_META_DATA).metaData.get("CHANNEL");
    } catch (NameNotFoundException e) {
        e.printStackTrace();
    }
}

Ant 在多渠道包上配置起来相对麻烦一点,如果你感兴趣的话可以参考这个博客 谦虚的天下-《App自动化之使用Ant编译项目多渠道打包》

而Gradle作为Android官方构建工具,批量打包自然会相对简单一点,就像下面这样简单配置一下即可:

 /**
 * -------------------------------------------------------
 * Flavors
 * --------------------------------------------------------
 */
productFlavors {

    intl {

        applicationId "com.smartphone.linux1s1s.international"

        versionName createVersionName(versionNameInit)

        manifestPlaceholders = [deeplinkScheme: "nlbtn2goint"]
    }

    gloav {

        applicationId "com.smartphone.linux1s1s.android"

        versionName createVersionName(versionNameInit)

        manifestPlaceholders = [deeplinkScheme: "nlbtn2go"]

    }
}

配置可以如此简单,但是批量打包还是绕不过从新构建这个过程,用一句通俗的话说就是,如果我需要1000个渠道包,每个渠道包需要5分钟,那么批量完成这些包需要5000分钟,Android在开发Gradle的时候可能完全想不到这个问题,因为除了天朝有这么多渠道市场外,其他国家都是望其项背,啰嗦几句后,咱们还是得面对现实,解决这个耗时的打包问题。

这里从最简单的情况说起,如果这么多渠道仅仅是区分不同的Channel,其他都相同。如果还有别的细微区别,这里暂且不考虑,话说回来,即使是这些细微的区别可能也仅仅是个别渠道,所以最笨的解决方法是从新构建这些个别渠道,其他都可以通过捷径来解决。

这个捷径是什么呢,当然是避免从新构建Build,如果不从新构建那么如果做到区分不同的渠道呢?

优化Build

我们先来看一下APK的构造

这个压缩目录中META-INF目录中的文件原则上是不参与签名的,所以我们可以通过在该文件中放入Channel标示而逃过从新构建,这样我们就可以直接通过文件操作来完成批量打包,而文件的复制解压压缩操作所消耗的时间和从新构建消耗的时间相比,简直可以忽略不计,上面就是整个打包方案的核心思想,接下来我们来实施上面的核心思想。

实际操作

在META-INF这个目录中添加一个以xxx_channelName_channelId命名的空文件,以xiaomi渠道举个例子如下所示:

然后再将解压后并添加相应文件的目录重新压缩为.apk格式的文件即可,上面的工作完成了,接下来就是批量添加文件过程了,这里给出Python脚本以供参考

Python脚本

#!/usr/bin/python
# coding=utf-8
import zipfile
import shutil
import os

# 空文件 便于写入此空文件到apk包中作为channel文件
src_empty_file = ‘xxxxx.txt‘
#创建一个空文件(不存在则创建)
with open(src_empty_file, ‘w‘) as f:
    pass

# 获取当前目录中所有的apk源包
src_apks = []
# python3 : os.listdir()即可,这里使用兼容Python2的os.listdir(‘.‘)
for file in os.listdir(‘.‘):
    if os.path.isfile(file):
        extension = os.path.splitext(file)[1][1:]
        if extension in ‘apk‘:
            src_apks.append(file)

# 获取渠道列表
channel_file = ‘channelConfig.txt‘

with open(channel_file) as f:

    for src_apk in src_apks:
        # file name (with extension)
        src_apk_file_name = os.path.basename(src_apk)
        # 分割文件名与后缀
        temp_list = os.path.splitext(src_apk_file_name)
        # name without extension
        src_apk_name = temp_list[0]
        # 后缀名,包含.   例如: ".apk "
        src_apk_extension = temp_list[1]

        # 创建生成目录,与文件名相关
        output_dir = ‘output_‘ + src_apk_name + ‘/‘
        # 目录不存在则创建
        if not os.path.exists(output_dir):
            os.mkdir(output_dir)

        # 遍历渠道号并创建对应渠道号的apk文件
        for line in f.readlines():
            # 获取当前渠道号,因为从渠道文件中获得带有\n,所有strip一下
            target_channel = line.strip()
            # 获取渠道号,从中分离出渠道name和渠道id
            target_channel_split = target_channel.split(‘_‘)
            target_channel_name = target_channel_split[0]
            #target_channel_id = target_channel_split[1]
            # 拼接对应渠道号的apk
            target_apk = output_dir + src_apk_name + ‘-release-‘ + target_channel_name + src_apk_extension
            # 拷贝建立新apk
            shutil.copy(src_apk,  target_apk)
            # zip获取新建立的apk文件
            zipped = zipfile.ZipFile(target_apk, ‘a‘, zipfile.ZIP_DEFLATED)
            # 初始化渠道信息
            empty_channel_file = "META-INF/xxxx_{channel}".format(channel = target_channel)
            # 写入渠道信息
            zipped.write(src_empty_file, empty_channel_file)
            # 关闭zip流
            zipped.close()

如有问题,欢迎交流。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-05 21:50:52

Android 多渠道打包方案的相关文章

Gradle实战:Android多渠道打包方案汇总

查看原文:http://blog.csdn.net/u010818425/article/details/52319382 Gradle实战系列文章: <Gradle基本知识点与常用配置> <Gradle实战:不同编译类型的包同设备共存> <Gradle实战:发布aar包到maven仓库> <Gradle实战:执行sql操作hive数据库> 本文将延续之前几篇博客的风格,先从基本概念入手,这有助于我们对后文的理解: 在后续的代码中如果忘了某个概念的具体意义,

Android 多渠道打包方式详解

Android 多渠道打包方式详解 面试的时候,如果面试官突然问到:你们渠道包是怎么打的?如果你说是用gradle一个一个编译的,然后他很鄙视的说这个效率太低啦,你们写过什么脚本自己打渠道包没?你肯定心里想,卧槽,这么狂炫吊炸天,自己写脚本打包?!其实这个根本也不是太难啦!!今天就来聊聊多渠道打包的原理以及如何自己DIY多渠道打包的工具! 渠道包出现 当一个产品到发版的时候,我们搞Android的就会面临一个超级尴尬的问题:国内这么多的渠道,渠道统计是必须做滴,那么十多个主要渠道再加无限量的地推

Android多渠道打包:极简实现方法

做安卓开发多年,总是在产品业务功能上兜兜转转,近来终于在了一个App完整的全流程开发体验:不仅是业务功能的开发,更介入到了App推广技术的领域,包括安装包快速下载.免填邀请码安装.排重防盗刷等等,对App推广技术的了解,让我感触很深,认识到产品业务功能再好,推广运营能力不行,也会在市场上举步维艰. 在对app推广技术的了解过程中,我发现了一款不错的安卓多渠道打包工具openinstall,它有几个优点值得称道,我在此推荐给大家.它的几个优点是: 优点一,首先是免费的: 优点二,openinsta

Android多渠道打包

产品每次发布,都需要打很多渠道的包.之前用per脚本打包,后来添加了自定义空间属性后,就不能打了.Ant脚本打包又嫌麻烦,引用的工程太多.最后想到一个办法就是反编译. 原理:每个渠道的包只有AndroidManifest.xml文件中渠道的ID不一样.所以反编译APK后,修改AndroidManifest.xml的渠道ID.最后重新打包. 步骤: 1.反编译已经打好包的APK(这里只用了-s,尝试过加上-r,但是AndroidManifest.xml文件没有被反编译,就删掉了) 1 java -

普通的多渠道打包方案

Android Gradle Plugin Gradle Plugin本身提供了多渠道的打包策略: 首先,在AndroidManifest.xml中添加渠道信息占位符: <meta-data android:name="InstallChannel" android:value="${InstallChannel}" /> 然后,通过Gradle Plugin提供的productFlavors标签,添加渠道信息: productFlavors{ &quo

android 多渠道打包

1.packerNg 式打包 Android应用使用的APK文件就是一个带签名信息的ZIP文件,根据 ZIP文件格式规范,每个ZIP文件的最后都必须有一个叫 Central Directory Record 的部分,这个CDR的最后部分叫"end of central directory record",这一部分包含一些元数据,它的末尾是ZIP文件的注释.注释包含Comment Length和File Comment两个字段,前者表示注释内容的长度,后者是注释的内容,正确修改这一部分不

Android 多渠道打包验证

原文链接:http://my.oschina.net/aibenben/blog/373596 作者自己编写了java验证脚本 使用VeidyapkTol.zip,在c盘根目录解压,会有两个文件夹,把你要验证的apk放到apk文件夹,然后打开apkTol文件夹里面,直接双击test.bat,OK! VeidyapkTol.zip 在文件目录下即可下载

Android 新一代多渠道打包神器

关于作者: 李涛,腾讯Android工程师,14年加入腾讯SNG增值产品部,期间主要负责手Q动漫.企鹅电竞等项目的功能开发和技术优化.业务时间喜欢折腾新技术,写一些技术文章,个人技术博客:www.ltlovezh.com . ApkChannelPackage是一种快速多渠道打包工具,同时支持基于V1和V2签名进行渠道打包.插件本身会自动检测Apk使用的签名方法,并选择合适的多渠道打包方式,对使用者来说完全透明. Github地址: https://github.com/ltlovezh/Apk

借腾讯开源 VasDolly,谈谈 Android 签名和多渠道打包的原理!

一.前言 Hi,大家好,我是承香墨影! 当我们需要发布一款 App 到应用市场的时候,一般需要我们针对不同的市场生产不同的渠道包,它们使用的是同一套代码,只是会包含一些各自的渠道信息,用于我们做数据分析. 前几天,企鹅电竞团队开源了自己的 Android Apk 多渠道打包工具:VasDolly,比美团的 Walle 更全面一些. 正好借这个机会,来讲解一下 Android 的不同版本的签名机制的差异. 二.Android 的签名 2.1 应用签名 通过对 Apk 进行签名,开发者可以证明对 A