Android多渠道打包

来源:互联网 发布:js省市区三级联动代码 编辑:程序博客网 时间:2024/06/16 15:17

一、Android Studio+gradle的方式打包

(一)在androidmanifest.xml中定义mate-data标签

二、第三方服务打包

这种方式就是使用第三方的服务,比如360,百度,友盟等,其原理也是通过修改androidManifest.xml中的mate-data标签内容,然后执行N次打包签名的操作实现多渠道打包的。这里就不在做具体解释说明,免得又做广告的嫌疑,O(∩_∩)O哈哈~。
优势:简单方便,几乎不用自身做什么工作;
劣势:打包速度过慢;

三、美团Android自动化之旅—生成渠道包

实现原理
Android应用安装包apk文件其实是一个压缩文件,可以将后缀修改为zip直接解压。解压安装文件后会发现在根目录有一个META-INF目录。如果在META-INF目录内添加空文件,可以不用重新签名应用。因此,通过为不同渠道的应用添加不同的空文件,可以唯一标识一个渠道。
“采用这种方式,每打一个渠道包只需复制一个apk,在META-INF中添加一个使用渠道号命名的空文件即可。这种打包方式速度非常快,900多个渠道不到一分钟就能打完。”
实现步骤
(一)编写渠道号文件
(二)编写Python脚本,实现解压缩apk文件,为META-INF目录添加文件,重新压缩apk文件等逻辑:

coding=utf-8

import zipfile
import shutil
import os

def delete_file_folder(src):
”’delete files and folders”’
if os.path.isfile(src):
try:
os.remove(src)
except:
pass
elif os.path.isdir(src):
for item in os.listdir(src):
itemsrc=os.path.join(src,item)
delete_file_folder(itemsrc)
try:
os.rmdir(src)
except:
pass

创建一个空文件,此文件作为apk包中的空文件

src_empty_file = ‘info/empty.txt’
f = open(src_empty_file,’w’)
f.close()

在渠道号配置文件中,获取指定的渠道号

channelFile = open(‘./info/channel.txt’,’r’)
channels = channelFile.readlines()
channelFile.close()
print(‘-‘*20,’all channels’,’-‘*20)
print(channels)
print(‘-‘*50)

获取当前目录下所有的apk文件

src_apks = [];
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)

遍历所以的apk文件,向其压缩文件中添加渠道号文件

for src_apk in src_apks:
src_apk_file_name = os.path.basename(src_apk)
print(‘current apk name:’,src_apk_file_name)
temp_list = os.path.splitext(src_apk_file_name)
src_apk_name = temp_list[0]
src_apk_extension = temp_list[1]

apk_names = src_apk_name.split('-');output_dir = 'outputDir'+'/'if os.path.exists(output_dir):    delete_file_folder(output_dir)if not os.path.exists(output_dir):    os.mkdir(output_dir)# 遍历从文件中获得的所以渠道号,将其写入APK包中for line in channels:    target_channel = line.strip()    target_apk = output_dir + apk_names[0] + "-" + target_channel+"-"+apk_names[2] + src_apk_extension    shutil.copy(src_apk,  target_apk)    zipped = zipfile.ZipFile(target_apk, 'a', zipfile.ZIP_DEFLATED)    empty_channel_file = "META-INF/uuchannel_{channel}".format(channel = target_channel)    zipped.write(src_empty_file, empty_channel_file)    zipped.close()

print(‘-‘*50)
print(‘repackaging is over ,total package: ‘,len(channels))
input(‘\npackage over…’)
(三)打包一个正常的apk包
(四)执行python脚本,多渠道打包
(五)android代码中获取渠道号
/**
* 渠道号工具类:解析压缩包,从中获取渠道号
*/
public class ChannelUtil {
private static final String CHANNEL_KEY = “uuchannel”;
private static final String DEFAULT_CHANNEL = “internal”;
private static String mChannel;

public static String getChannel(Context context) {    return getChannel(context, DEFAULT_CHANNEL);}public static String getChannel(Context context, String defaultChannel) {    if (!TextUtils.isEmpty(mChannel)) {        return mChannel;    }    //从apk中获取    mChannel = getChannelFromApk(context, CHANNEL_KEY);    if (!TextUtils.isEmpty(mChannel)) {        return mChannel;    }    //全部获取失败    return defaultChannel;}

/**
* 从apk中获取版本信息
*
* @param context
* @param channelKey
* @return
*/
private static String getChannelFromApk(Context context, String channelKey) {
long startTime = System.currentTimeMillis();
//从apk包中获取
ApplicationInfo appinfo = context.getApplicationInfo();
String sourceDir = appinfo.sourceDir;
//默认放在meta-inf/里, 所以需要再拼接一下
String key = “META-INF/” + channelKey;
String ret = “”;
ZipFile zipfile = null;
try {
zipfile = new ZipFile(sourceDir);
Enumeration

原创粉丝点击