Android多渠道打包方案的实践与优化

目前使用过的多渠道打包方式有两种 ,一种是通过gradle打包,还有一种是美团的多渠道打包方案具体详情见这里

1、Gradle打包

1.1、在Androidmanifest.xml中添加

        <meta-data
            android:name="UMENG_CHANNEL"
            android:value="${UMENG_CHANNEL_VALUE}" />

1.2、在build.gradle中添加

     productFlavors {
         // 百度
         baidu {
             manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu"]
         }
         //魅族
         meizu {
             manifestPlaceholders = [UMENG_CHANNEL_VALUE: "meizu"]
         }
         //搜狗
         sougou {
             manifestPlaceholders = [UMENG_CHANNEL_VALUE: "sougou"]
         }

这时候在Android Studio右侧的Gradle project工作区中就可以看到在这里配置的多个渠道了,双击相应的选项就能build出相应的渠道包了,assembleRelease是build出所有渠道的Release包,这里只使用了少量的渠道作为示例。这里的UMENG_CHANNEL_VALUE需要和meta-data中的value一致才能替换。
这里写图片描述

1.3、获取渠道号

    public static String getApplicationMetadata(Context context,
                                                String metaDataKey) {
        ApplicationInfo info = null;
        try {
            PackageManager pm = context.getPackageManager();

            info = pm.getApplicationInfo(context.getPackageName(),
                    PackageManager.GET_META_DATA);

            return String.valueOf(info.metaData.get(metaDataKey));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

这里的metaDataKey自然就是UMENG_CHANNEL了

2、美团多渠道打包方案

2.1、环境配置

由于美团的多渠道打包方案需要依靠脚本来实现,这里我用的是python,经试验脚本文件在windows 下用3.6版本和mac下用2.7版本都能完美运行。并且需要安装openpyxl模块。

2.2、文件说明

打包的文件有channels.xlsx 和 package.py
channels.xlsx是一个excel表格里面第一列是渠道号的id,第二列是渠道号的名称,第三列是渠道名称的备注(非必须)

这里写图片描述

package.py 是一个python脚本文件

import datetime
import zipfile
import shutil
import sys
import os
from openpyxl import load_workbook

starttime = datetime.datetime.now()
apk_path = sys.argv[1]
print(os.path.abspath(apk_path))
file_path=os.path.dirname(os.path.abspath(apk_path))+os.path.sep
out_path =file_path+'output'

if not os.path.exists(out_path):
    os.makedirs(out_path)
else:
    shutil.rmtree(out_path,True)
    os.makedirs(out_path)

name = os.path.basename(apk_path)
origin_apk_name = os.path.splitext(name)[0]
wb=load_workbook(filename=file_path+'channels.xlsx',read_only=True)
sheets = wb.get_sheet_names()
ws=wb[sheets[0]]

for row in ws.rows:
    idStr=str(row[0].value)
    channelStr=str(row[1].value)
    channel_apk_name='{}-{}-{}.apk'.format(idStr,channelStr,origin_apk_name)
    channel_apk_path=os.path.join(out_path,channel_apk_name)
    shutil.copy2(apk_path,channel_apk_path)
    zipped=zipfile.ZipFile(channel_apk_path,'a',zipfile.ZIP_DEFLATED)
    empty_channel_file="META-INF/channel_{}_{}".format(idStr,channelStr)
    zipped.writestr(empty_channel_file, '')
    zipped.close()
    print(idStr+":"+channelStr)

endtime=datetime.datetime.now()
between=(endtime-starttime).microseconds/1024
print('time:%d ms' % between)

2.3、运行脚本

在命令行中输入 python package.py xxxx.apk
如果Python命令是在package.py所在目录下用上面的方式输入,也可以将package.py和apk文件直接拖入命令窗口中执行,然后就会在apk所在路径下生成一个output文件夹里面有所有生成的渠道包。

2.4、获取渠道号

这时候用Android Studio 打开新生成的渠道包,Build——>Analyze Apk选中刚才生成的apk打开META-INF文件夹可以看到这样的的一个文件channel_{id}_{name}的文件,由于它是一个空文件,所以可以看到它的体积大小为0B。因此新的渠道包也不会需要重新签名。

这里写图片描述

代码中获取渠道号

    public static String[] getChannel() {
        ApplicationInfo appinfo = App.getInstance().getContext().getApplicationInfo();
        String sourceDir = appinfo.sourceDir;
        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("META-INF/channel")) {
                    ret = entryName;
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (zipfile != null) {
                try {
                    zipfile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        String[] split = ret.split("_");
        if (split != null && split.length >= 2) {
            for (int i = 0; i < split.length; i++) {
                Logger.e(split[i]);
            }
            return split;

        } else {
            return null;
        }
    }

在这里获取到的split信息应该是[“META-INF/channel”,”18”,”uc”],然后获取自己需要的信息就好了

3、两种打包方式对比

打包方式特点优点缺点适用场景
gradleproductFlavors下配置渠道号,assembleRelease一键执行打完所有包配置简单每个包都需要重新build,耗时较长渠道包较少时
美团多渠道打包方案通过脚本文件在apk的META-INF目录下生成包含渠道号的空文件打包速度快需要依赖外部的脚本文件来实现,修改脚本有学习成本渠道包比较多时

4、遇到的其他问题

4.1、umeng的渠道号设置

这种方式不会替换meta-data中的信息,好在umeng提供了在代码中设置channel的方法,详情见这里

4.2、注意事项

渠道包的位置一定要和channel的配置文件在同一目录下

4.3、打包方式优化

这种方式还是需要自己输入命令行,稍后打算写一份.bat文件让他双击运行。

打包脚本下载

转载请注明出处:http://blog.csdn.net/zhong1113/article/details/54094770

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值