Android 打包三种方式实例详解
android 打包三种方式实例详解
前言:
现在市场上很多app应用存在于各个不同的渠道,大大小小几百个,当我们想要在发布应用之后统计各个渠道的用户下载量,我们就要进行多渠道打包。
01.应用的打包签名什么是打包?
打包就是根据签名和其他标识生成安装包。
签名是什么?
1.在android应用文件(apk)中保存的一个特别字符串
2.用来标识不同的应用开发者:开发者a,开发者b
3.一个应用开发者开发的多款应用使用同一个签名
就好比是一个人写文章,签名就相当于作者的署名。
如果两个应用都是一个开发者开发的,那么签名就是一样的。
这个开发者,可以是个人,也可以是公司、团体。
为什么要用签名?原因1:最简单直接的回答: 系统要求的。
android系统要求每一个android应用程序必须要经过数字签名才能够安装到系统中,也就是说如果一个android应用程序没有经过数字签名,是没有办法安装到系统中的!
原因2:
不同程序员开发的应用包名可能会相同, 导致一个应用覆盖掉另一个应用。
如果只有包名的概念,那么如果b应用与已经安装的a应用包名一样,那就实现覆盖。不合理!
而事实上是装不上b的,它会提示,存在包名一致,但是签名不一样的。这就不会覆盖。
如何为apk签名?
如何签名就不用说了,这方面的博文数不胜数,相信看这篇文章的你也应该会。
在代码中得到应用的签名?(个人觉得没啥用)
public void getsinginfo() { try { packageinfo packageinfo = getpackagemanager().getpackageinfo( "应用包名", packagemanager.get_signatures); signature[] signs = packageinfo.signatures; signature sign = signs[0]; parsesignature(sign.tobytearray()); } catch (exception e) { e.printstacktrace(); } } public void parsesignature(byte[] signature) { try { certificatefactory certfactory = certificatefactory .getinstance("x.509"); x509certificate cert = (x509certificate) certfactory .generatecertificate(new bytearrayinputstream(signature)); string pubkey = cert.getpublickey().tostring(); string signnumber = cert.getserialnumber().tostring(); log.e("tag", "pubkey:" + pubkey); log.e("tag", "signnumber:" + signnumber); } catch (exception e) { e.printstacktrace(); } }
注意问题:
现象:
android导出apk包时出现,编译调试时不会出现。
错误信息:
error:(16) error: “baidutieba_client_inavailable” is not translated in “en” (english) [missingtranslation]
error:(63) error: “baidutieba” is not translated in “en” (english) [missingtranslation]
error:(67) error: “share_to_baidutieba” is not translated in “en” (english) [missingtranslation]
错误截图:
解决办法:
resources 标签内增加两个属性即可:
<?xml version="1.0" encoding="utf-8" ?> <resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="missingtranslation"> </resources>
02.友盟的多渠道打包说明:1.什么是多渠道包?
渠道包就是要在安装包中添加渠道信息,也就是channel,对应不同的渠道,例如:小米市场、360市场、应用宝市场等
2.为什么要提供多渠道包?
我们要在安装包中添加不同的标识,应用在请求网络的时候携带渠道信息,方便后台做运营统计(这就是添加渠道信息的用处)。
3.实现多渠道打包的原理:
一般来讲,这个渠道的标识会放在androidmanifest.xml的application的一个metadata中。然后就可以在java中通过api获取对应的数据了。
4.如何实现?
现在android渠道多种多样,其实渠道不仅仅局限于应用市场,一种推广方式也可以看做一个渠道,比如:通过人拉人的方式去推广,官网上推广,百度推广等。所以说渠道成千上万,为了推广,有时候一次也会打成千的安装包,那你半天或者一天啥都别干了,所以介绍几个大公司高效的打包方式,借鉴一下。
第一种:友盟就提供了多渠道打包的方式,可用于渠道统计等。
现在android的构建工具换成了gradle,通过gradle,简单配置后就可以实现自动打所有渠道包。
实现步骤:
1.按照umeng的要求,manifest文件中需要有
<meta-data android:name="umeng_channel" android:value="${umeng_channel_value}" />
这段配置,value那里就是wandoujia,360之类的渠道名称,但是我们在这里不会去写渠道名,写的是一个占位符,后面gradle编译的时候会动态的替换掉它。
2、在module(一般也就是app)的build.gradle的android{}中添加如下内容:
productflavors{ wandoujia{ manifestplaceholders = [umeng_channel_value: "wandoujia"] } xiaomi{ manifestplaceholders=[umeng_channel_value: "xiaomi"] } }
productflavors是android节点的一个自节点。你需要打什么渠道的包,就在这里按umeng的要求用渠道名给umeng_channel_value赋值。
3、优化1:上面只是两个渠道,如果有几十个渠道,都这样写,重复的东西太多,观察到每个渠道就是flavor的名称,所以修改如下:
productflavors{ wandoujia{ } xiaomi{ } } productflavors.all { flavor -> flavor.manifestplaceholders = [umeng_channel_value: name] }
4、优化2:上面经过签名打包后生成的apk的名称是有默认命名规则的,如:xxx-xiaomi-release.apk 但是我们想包含版本信息如:xxx-xiaomi-release-1.0.apk,所以最终打包脚本如下:
productflavors{ wandoujia{ } xiaomi{ } } productflavors.all { flavor -> flavor.manifestplaceholders = [umeng_channel_value: name] } applicationvariants.all { variant -> variant.outputs.each { output -> def outputfile = output.outputfile if (outputfile != null && outputfile.name.endswith('.apk')) { def filename = outputfile.name.replace(".apk", "-${defaultconfig.versionname}.apk") output.outputfile = new file(outputfile.parent, filename) } } }
4.获取渠道
在代码中我们可以通过读取mate-data信息来获取渠道,然后添加到请求参数中,获取方法如下:
private string getchannel() { try { packagemanager pm = getpackagemanager(); applicationinfo appinfo = pm.getapplicationinfo(getpackagename(), packagemanager.get_meta_data); return appinfo.metadata.getstring("umeng_channel"); } catch (packagemanager.namenotfoundexception ignored) { } return ""; }
5、执行签名打包
这时候你去app/build/outputs/apk中就能看到自动打好的渠道包了。
6、缺点:
这样的打包方式效率比较低下,如果是几十个包还可以应付,打一个包快的话需要十几秒,慢的话需要几分钟不等,跟机器性能很有关系。
03、美团多渠道打包原理:
把一个android应用包当作zip文件包进行解压,然后发现在签名生成的目录下(meta-inf)添加一个空文件不需要重新签名。利用这个机制,该文件的文件名就是渠道名。这种方式不需要重新签名等步骤,非常高效,但是貌似在android7.0之后,google为了增强签名的安全性,采用了新的签名规则,不是针对每个文件来进行数字编码,而是对zip包文件结构编码签名后产生一个唯一的数据叫做apk signing block。如果修改了zip文件的任何模块的内容,apk signing block都会发生改变,从而无法再绕过签名机制。
方法:
首先你需要去下载相关的工具:
详细步骤:
1、将要打包的apk放到pythontool中
2、在pythontool/info/channel.txt中写入需要的渠道,一个渠道占一行
3、双击执行pythontool/multichannelbuildtool.py文件(需要python环境),就会生成渠道包
4、获取渠道信息:将javautil文件中的channelutil.java拷贝到工程,调用channelutil.getchannel即可获取渠道.
优缺点:
优点:
这种打包方式速度非常快,900多个渠道不到一分钟就能打完
缺点:
1、google现在已经修改了新的签名规则,若使用新的签名规则则无法使用(老的无所谓)。
2、一些不法的渠道商很容易通过工具修改渠道,如果一个渠道商,通过网络劫持和篡改渠道的组合方式来获取暴利,对于程序开发者来说可能会存在着巨大的经济损失
04、360多渠道打包:
apk文件本质就是zip文件,利用zip文件“可以添加comment(摘要)”的数据结构特点,在文件的末尾写入任意数据,而不用重新解压zip文件,我们就可以将渠道信息写入摘要区
方法:
首先还是去下载相关工具:
步骤:
1、将要写入渠道信息的apk放入mcptool文件夹中
2、修改mcptool.bat批处理文件,更改渠道和密码(渠道信息为了安全需要加密)
3、将apk拖到mcptool.bat上执行,将会生成渠道包
4、修改mcptool-check.bat中的密码和mcptool.bat中的密码一致
5、将渠道包拖到mcptool-check.bat上执行,就可以检查渠道信息是否正确
6、获取渠道:将mcptool.java添加到工程或者将mcptool.jar导入工程,调用 mcptool.getchannelid(this,”12345678”,”“) 第一个参数为context,第二个是密码,第三个是默认值。
优缺点:
优点:
1、5m的apk,1秒种能打300个
2、在下载apk的同时,服务端可以写入一些信息,例如邀请码,分享信息等
缺点:
渠道信息也是很容易修改,虽然可以加密,只是提高了修改的门槛
以上就是多渠道打包的一些方法,目前大部分公司常用的还是友盟的打包方式。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!