1、自动化打包方案

 1)友盟多渠道多渠道打包

2)gradle productFlavors系统的条件编译

3)美团打包

4)APK文件注释写入渠道号

2、各打包方案简介

1)友盟多渠道多渠道打包(window 绿色版,gradle版本 现在过时)

原理:拆包分解apk,修改AndroidManifest.xml二进制文件后,再重新打包

耗时:较短(多渠道打包时,避免了多次dex过程,aapt过程)

渠道号保存方式:保存在AndroidManifest.xml 文 件 meta 数据中

不足:较难保证AndroidManifest.xml二进制修改正确,可能会出现兼容性问题;多渠道apk 命名不能预定,需要额外处理重命名apk文件。

2).gradle productFlavors系统的条件编译

  

原理: 每个渠道包,都走完整个打包(appt、混淆、dex,签名)流程

耗时:长(跟渠道包量成正比)

渠道号保存方式:保存在AndroidManifest.xml 文 件 meta 数据中

3)美团方案

原理:在APK文件的META-INF目里增加渠道文件

耗时:快(多个渠道包,只有一次完整打包流程)

渠道号保存方式:mtchannel_yybcpd文件名中

4)APK文件注释写入渠道号

原理:Android 使用的apk包的压缩方式是zip,与zip有相同的文件结构,正确写入 File Comment 部分,不破坏压缩包、不用重新打包前提下,写入自己想要的数据。

耗时:快

渠道号保存方式:保存在zip 注释中。

3、android 打包流程和签名机制:

  1)android 打包流程

ps:代码混淆在dx 生成dex 之前进行。

2)签名机制

(1)生成MANIFEST.MF文件 遍历apk包中的所有文件(entry),对非文件夹非签名 文件的文件,逐个生成SHA1的数字签名信息,再用 Base64进行编码

(2)生成CERT.SF文件 对生成的Manifest,使用SHA1-RSA算法,用私钥进 行签名

(3)生成CERT.RSA文件 对CERT.SF文件做签名,内容存档(公钥、所采用的加 密算法)到中CERT.RSA

ps:从第一步规则源码,/build/tools/signapk/SignApk.java ,关键源码代码如下:

从源码中,可以看出空文件夹免签名,并看不出来美团方案怎样规避签名机制。

从apk安装过程签名校验关键类:PackageParser.java   collectCertificates()方法:

  从上图可以看空文件夹和META-INFO文件夹中的文件、AndroidManifest.xml免签名检验的,美团就是通过在META-INFO文件夹

新增渠道号文件,实现多渠道打包,当然不需要进行zipalign操作(通过zipalign -c -v 4 application.apk检验包是否已经对齐)。

4、python实现方案3和方案4(python2.7 windos环境):

  1)思路:1.执行gradle 打包命令

     2.监听gradle 打包进程,打包结束后

      方案3:拷贝apk,对apk进行zipfile 文件操作,在META-INFO文件夹中新增多渠道文件。

      方案4:拷贝apk,对apk添加zip comment.

    

  2)python代码实现:

         (1)执行gradle 打包命令     

  cmd = 'gradle assembleInnerRelease ' #假设 builde.gradle productFlavors 中配置inner
  pro = subprocess.Popen(cmd,shell = True)

  (2)监听进程(做了简单的封装)

   

#监听进程 用来监听gradle 打包进程,后文微信资源混淆进程等
def func_listen_process(Process,listener):
if listener == None or not isinstance(listener,ProcessListener):
print 'func_listen_process: ' + process + ' listener is null or not processListener interface'
return listener.start() while (True):
time.sleep(1)
retCode = subprocess.Popen.poll(pro)
if retCode is not None:
listener.end()
break
else:
listener.doing() #抽象类加抽象方法就等于面向对象编程中的接口
from abc import ABCMeta,abstractmethod
#定义接口
class ProcessListener:
__metaclass__ = ABCMeta #指定这是一个抽象类
@abstractmethod #抽象方法
def start(self):
pass
@abstractmethod #抽象方法
def doing(self):
pass
@abstractmethod #抽象方法
def end(self):
pass

   (3)监听gradlle打包进程

#监听gradle 打包进程
func_listen_process(pro,GradlePackProcessListener())
#gradle打包进程监听器
class GradlePackProcessListener(ProcessListener):
curTime = 0
apkCount = 0 def __init__(self):
return
def start(self):
self.curTime = time.time()
def doing(self):
return
def end(self):
    apkCount = func_channelsReleasePack(workSpace)
self.curTime = time.time() - self.curTime;
print "\nandroid channels pack cost total time : " + str(int(self.curTime)) +'s , ' + str(apkCount) + ' apks' #多渠道打正式包 channelsFile.txt 每行一个渠道号
def func_channelsReleasePack(workSpace):
apkPath = workSpace + '/build/outputs/apk'
channelsFile = open(workSpace + '/channelsFile.txt', "r")
apks = []
countApk = 0
global version print u"\nstart channle release pack\n" while True:
channelName = channelsFile.readline()
channelName = channelName.strip('\n').strip('\t') if channelName:
channelApkName = apkPath + '/' + apkPrefix + '_' + channelName + '_' + version +'.apk'
shutil.copyfile(apkPath+'/' + apkPrefix + '_inner_' + ''+ version +'.apk',channelApkName)
apks.append(apkPrefix + '_' + channelName + '_' + version +'.apk')
zipped = zipfile.ZipFile(channelApkName, 'a', zipfile.ZIP_DEFLATED)
empty_channel_file = "META-INF/channel_{channel}".format(channel = channelName)
newChannelFile = open(apkPath+'/channel_'+ channelName, 'w')
newChannelFile.close()
zipped.write(apkPath+'/channel_'+ channelName,empty_channel_file)
zipped.close();
os.remove(apkPath+'/channel_'+ channelName)
print '---> /' + apkPrefix +'_' + channelName + '_' + version +'.apk' countApk = countApk + 1; else:
channelsFile.close()
#删除出多余的文件
func_delFiles(apkPath,apks)
break
print u"\nend channle release pack"
#func_zipalignApks(apks)
return countApk;

(4)获取应用获取渠道号(这里只给出方案3渠道号获取方法,方案四渠道号获取方法见一种为 Apk 动态写入信息的方案):

/**
* 获取友盟渠道
* #app安装后,拷贝保存在/data/app/目录下
* @return
*/
public static String getChannel(Context mContext) {
ApplicationInfo appinfo = mContext.getApplicationInfo();
String sourceDir = appinfo.sourceDir;
String ret = "";
ZipFile zipfile = null;
try {
Log.d("sihaixuan", "app source dir : " + sourceDir);
zipfile = new ZipFile(sourceDir);
Enumeration<?> entries = zipfile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = ((ZipEntry) entries.nextElement());
String entryName = entry.getName();
Log.d("sihaixuan",entryName + "");
if (entryName.contains("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) {
return ret.substring(split[0].length() + 1); } else {
return "";
}
}

(5)打包测试

5、总结

  

ps:gradle 定义 task 也可以实现以上方案,新一代Android渠道打包工具:1000个渠道包只需要5秒实现了apk 注释添加渠道号

github:AndroidPackCi

参考资料:

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

   新一代Android渠道打包工具:1000个渠道包只需要5秒

友盟渠道打包工具

Android签名机制之---签名过程详解

Android源码查看网址http://androidxref.com/

一种为 Apk 动态写入信息的方案

自动化打包资源混淆集成python实践----打包的更多相关文章

  1. 自动化打包资源混淆集成python实践----资源混淆

    前面自动化打包资源混淆集成python实践----打包一文讲述了四种打包方案,以及美团打包方案.apk注释添加渠道号方案的实现.这里讲集成资源混淆. 1.资源混淆带来的好处: 1)对资源文件起一定的保 ...

  2. python程序打包

    环境: CentOS6.5_x64Python版本 : 2.6 使用pyinstaller打包 pyinstaller可以将python程序打包成二进制文件,打包后的文件在没有python的环境中也可 ...

  3. 自动化打包 Jenkins 持续集成 Git Gradle MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  4. 将python代码打包成一个app/exe

    前言 打包的代码通常都需要写一个简单的界面,一般用PyQt来写.用PyQt写界面的方法请戳这里:PyQt5的安装及基本配置    PyQt5教程 python提供了几个用来打包的模块,主要有py2ap ...

  5. UmengAppDemo【友盟统计SDK集成以及多渠道打包配置,基于V7.5.3版本】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这里只是记录下集成友盟统计SDK以及简单配置多渠道打包的步骤.所以1.该Demo不能运行:2.配置多渠道打包只是一种简单的写法,具体 ...

  6. 基于Armitage的MSF自动化集成攻击实践

    基于Armitage的MSF自动化集成攻击实践 目录 0x01 实践环境 0x02 预备知识 0x03 Armitage基础配置 0x04 Nmap:Armitage下信息搜集与漏洞扫描 0x05 A ...

  7. python之打包、发布模块

    一.python中针对于写好的模块,并且比人也可以使用改模块,这样就可以以同意的打出来,让别人安装或者赋值过后可以更好的使用以及集成. 二.最近在学习python所以这里主要是记录一下python的打 ...

  8. python实战===python程序打包成exe

    推荐PyInstaller项目www.pyinstaller.org   安装方法: 先跑pip install pywin32再跑pip install pyinstaller即可 可用一句命令打包 ...

  9. 转:美团Android资源混淆保护实践

    转自:http://tech.meituan.com/mt-android-resource-obfuscation.html 前言 Android应用中的APK安全性一直遭人诟病,市面上充斥着各种被 ...

随机推荐

  1. bzoj 2115 [Wc2011] Xor——路径和环的转化

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2115 思路很精妙.好像能应用到很多地方. 发现如果路径上有环,可以通过一些走法达到 异或了那 ...

  2. 浅谈Java中的对象和对象引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  3. 四川第七届 I Travel(bfs)

    Travel The country frog lives in has nn towns which are conveniently numbered by 1,2,…,n1,2,…,n. Amo ...

  4. Codeforces Problem - 38E - Let's Go Rolling!(DP)

    E. Let's Go Rolling! time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  5. Mongodb 分片与副本集

    测试搭建192.168.3.110mongos 30000,30001,30002config 40000,40001,40002shard1 50001,50002,50003shard2 5000 ...

  6. Ubuntu登录异常: 输入正确的密码, 但是却无法进入系统, 总是返回到登录界面, 但是用ctrl+alt+F1-F文字界面登录都可以进入。

    今天打开电脑的时候, 在输入密码之后, 未进入ubuntu的桌面, 而是显示了几行英文之后有返回到了登录界面.显示的英文如下: could not write bytes: Broken pipe   ...

  7. CS231n 2016 通关 第三章-SVM与Softmax

    1===本节课对应视频内容的第三讲,对应PPT是Lecture3 2===本节课的收获 ===熟悉SVM及其多分类问题 ===熟悉softmax分类问题 ===了解优化思想 由上节课即KNN的分析步骤 ...

  8. Oracle的REGEXP_REPLACE函数简单用法

    转载:http://blog.csdn.net/itmyhome1990/article/details/50380718

  9. CSS——盒子模型

    一.盒子模型: 模型如下: 如图:盒子模型包括:margin.padding.border.content四部分. margin:外边距,透明,能够显示父级的背景颜色等.表示元素与元素之间的间隔或者说 ...

  10. linux命令-su切换用户

    查看当前用户 #id uid=0(root) gid=0(root) 组=0(root) #whoami root ////////////////////////////////////////// ...