目前Android多渠道打包主要两种方式:

Gradle方式。

在build.gradle配置:

 productFlavors {        huawei {            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "huawei"]        }        xiaomi {            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]        }        ...    }

渠道多的时候会导致gradle文件很长,如果想简化书写可以这样做:
在build.gradle中配置如下:

Properties properties = new Properties()properties.load(project.rootProject.file('local.properties').newDataInputStream())...android{    ...    productFlavors {            def channelArray = properties.getProperty("channel").split(";");            for (int i = 0; i < channelArray.size(); i++) {                def channel = channelArray[i]                "${channel}" {                    manifestPlaceholders = [CHANNEL_VALUE: channel]                }            }        }        ...}        

local.properties中添加所有渠道号:channel=wandoujia;_360;yingyongbao;xiaomi;baidu;huawei;...

当渠道很多的时候,每次打包的时间要几十分钟到几个小时,那么有没有更快速的方式呢,请看第二种方式。

META-INF方式。

使用此种方式可以动态获取当前渠道号,极大节省了打包时间。

    /**     * 友盟配置     在application onCreate方法调用     */    private void umengConfig() {        String channel = getChannelFromApk(application, "channel-");        if (TextUtils.isEmpty(channel)) {            channel = "default";        }        if (BuildConfig.IS_DEBUG) {            Toast.makeText(application, "当前渠道:" + channel, Toast.LENGTH_SHORT).show();        }        AnalyticsConfig.setChannel(channel);    }         /**     * 从apk中获取版本信息     * @param context     * @param channelPrefix 渠道前缀     * @return     */    public static String getChannelFromApk(Context context, String channelPrefix) {        //从apk包中获取        ApplicationInfo appinfo = context.getApplicationInfo();        String sourceDir = appinfo.sourceDir;        //默认放在meta-inf/里, 所以需要再拼接一下        String key = "META-INF/" + channelPrefix;        String ret = "";        ZipFile zipfile = null;        try {            zipfile = new ZipFile(sourceDir);            Enumeration<?> entries = zipfile.entries();            while (entries.hasMoreElements()) {                ZipEntry entry = ((ZipEntry) entries.nextElement());                String entryName = entry.getName();                if (entryName.startsWith(key)) {                    ret = entryName;                    break;                }            }        } catch (IOException e) {            e.printStackTrace();        } finally {            if (zipfile != null) {                try {                    zipfile.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }        String[] split = ret.split(channelPrefix);        String channel = "";        if (split != null && split.length >= 2) {            channel = ret.substring(key.length());        }        return channel;    }

每次动态获取应用包下meta-inf文件夹中的渠道文件取得渠道号,那么meta-inf下的渠道文件如何添加呢?我们可以使用python脚本来做这件事。

#!/usr/bin/python# coding=utf-8import zipfileimport shutilimport osimport ConfigParser#读取配置文件config = ConfigParser.ConfigParser()config.read("channels-config.ini")#apk路径apk_path = config.get("Build-Config", "apk.path")print "src apk path=" + apk_path#渠道识别前缀channel_prefix = config.get("Build-Config", "channel.prefix")print "channel prefix=" + channel_prefix#渠道列表channel_list = config.get("Build-Config", "channel.list")print "channel list=" + channel_list#解析渠道,生成渠道数组channel_array = channel_list.split(',')# 空文件 便于写入此空文件到apk包中作为channel文件src_temp_file = 'temp_.txt'# 创建一个空文件(不存在则创建)f = open(src_temp_file, 'w')f.close()src_apk = apk_path# file name (with extension)src_apk_file_name = os.path.basename(src_apk)# 分割文件名与后缀temp_list = os.path.splitext(src_apk_file_name)# name without extensionsrc_apk_name = temp_list[0]# 后缀名,包含.   例如: ".apk "src_apk_extension = temp_list[1]# 创建生成目录,与文件名相关output_dir = 'apks_' + src_apk_name + '/'# 目录不存在则创建if not os.path.exists(output_dir):    os.mkdir(output_dir)# 遍历渠道号并创建对应渠道号的apk文件for line in channel_array:    # 获取当前渠道号,因为从渠道文件中获得带有\n,所有strip一下    target_channel = line.strip()    # 拼接对应渠道号的apk    target_apk = output_dir + src_apk_name + "-" + target_channel + src_apk_extension    # 拷贝建立新apk    shutil.copy(src_apk,  target_apk)    # zip获取新建立的apk文件    zipped = zipfile.ZipFile(target_apk, 'a', zipfile.ZIP_DEFLATED)    # 初始化渠道信息    target_channel_file = "META-INF/" + channel_prefix + "{channel}".format(channel = target_channel)    # 写入渠道信息    zipped.write(src_temp_file, target_channel_file)    # 关闭zip流    zipped.close()#删除临时文件os.remove(src_temp_file)

channels-config.ini文件如下:

[Build-Config]apk.path = your apk pathchannel.prefix = channel-channel.list = baidu,xiaomi

更多相关文章

  1. Gradle配置文件详解
  2. Android对APK文件的安装和卸载
  3. android aidl文件分析
  4. 在Mac上完全删除android studio初始配置文件
  5. android 客户端与服务器交互 UDP方式。
  6. android 开发中的文件操作

随机推荐

  1. android微信分享、微信支付的一些坑
  2. Eclipse中使用Ant打Android包报错及解决
  3. Kitkat 的磁盘加密功能分析
  4. Android(安卓)SDK中的Support兼容包详解
  5. Android的SeekBar和RateBar的使用-androi
  6. Android(安卓)Camera Framework Stream
  7. Android如何获取SIM卡信息
  8. android:textAppearance
  9. android添加WMS图层
  10. Android(安卓)浏览器的研究---启动(一)