本文主要是介绍关于多渠道打包的最强攻略--总结版,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
原始多渠道打包
原始多渠道打包的方式,指的是每次打包的时候在代码中设置channelId,打包完这个渠道的apk包后,需要重新设置channelId再进行打包,如此反复。该方式多出现在android早期的时候,多被一些刚入行的android工程师使用,或者是一些公司面对较少渠道的时候使用。
原理
原始多渠道打包就是个体力活,在较少渠道的时候可以使用,但是面对上千的渠道的时候,使用这种方式你会后悔当一名android开发工程师。它的原理是在应用代码中设置渠道ID,使用的时候将渠道ID设置给数据分析接口,数据分析平台通过该渠道ID分析之。其实后面多渠道方式的本质原理都是这样的,但是具体扩展方式不同而已,将在后面的分析的时候介绍。
实现
- 第一步:设置渠道id
方式一 在代码中直接设置channelId
- 1
- 1
方式二 在AndroidMainfest.xml中application中设置meta-data
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
在代码中获取channelId
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
- 第二步:集成到sdk中,比如友盟sdk
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
优缺点
在渠道较少(个位数)的时候可以使用,但对于多渠道的时候太耗时耗力了。
友盟多渠道打包
该方法是友盟几年前公布的多渠道打包方式,并且在github开源了打包工具,友盟多渠道打包方式经历了多次迭代,主要有两种方式,一种是通过反编译apk修改渠道信息,另一种是通过AXML解析器编辑修改渠道信息。
原理
-
第一种方法:
通过ApkTool进行解包,然后修改AndroidManifest中修改渠道标示,最后再通过ApkTool进行打包、签名。 -
第二种方法:
使用AXML解析器axmleditor.jar,拥有很弱的编辑功能,工程中用来编辑二进制格式的 AndroidManifest.xml 文件.
实现
- 第一步 apktool解包apk
apktool是一个逆向工程工具,可以用它解码(decode)并修改apk中的资源。接下来详细介绍如何使用apktool生成渠道包。
在Android多渠道打包(一)介绍过,同样需要在AndroidManifest.xml文件中定义元素,并在应用启动的时候读取清单文件中的渠道号。打包时,只需构建一次生成一个apk,然后在该apk的基础上生成其他渠道包即可。
首先,使用apktool decode应用程序,在终端中输入如下命令:
apktool d your_unsigned.apk build
解包后生成如下图片的文件
- 第二步 使用python脚本修改AndroidManifest.xml中的渠道号
AndroidManifest.xml文件内容
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
Python脚本
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
或者使用AXML解析器直接编辑修改AndroidManifest.xml中的渠道号
- 第三步 使用apktool重新构建未签名的apk
apktool b build your_unsigned_apk
- 第四步 使用jarsigner重新签名apk
jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore your_keystore_path -storepass your_storepass -signedjar your_signed_apk, your_unsigned_apk, your_alias
- 另在代码中集成,比如友盟sdk
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
官方说明
- 最近更新
友盟本次更新最大的改变是放弃了 V2.x 版本中通过 Apktool 反编译apk文件打包的方式,这种打包方式会对开发的apk文件做出大幅度的修改,可能会产生许多不兼容的问题,比如对jar包中包含资源的情况无法支持,对包含 .so 文件的apk兼容性也不好,而且在打包时 AndroidManifest.xml 文件中的特殊标签会丢失。为了解决这些问题减少对开发者apk文件的修改, 我们决定放弃这种方式,而采用直接编辑二进制的AndroidManifest.xml 文件的方式。这种方式只会修改 AndroidManifest.xml 文件,对于apk包中的资源文件和代码文件都不会做任何改变。如果打包不成功,生成的apk文件有问题,在测试阶段也可以快速发现,因为修改只会影响AndroidManifest.xml 相关的少量的设置。
- 工具使用
axmleditor.jar 一个AXML解析器,拥有很弱的编辑功能,工程中用来编辑二进制格式的 AndroidManifest.xml 文件.
JarSigner.jar 给 Apk 签名, SignApk.jar 文件是我们修改过的 apk 签名工具,实现了和 ADT 中一样的签名方式.
这些Java工具都是使用java7编译的,如果您还在使用Java 1.6 请留下issue。
DotNetZip 解压缩和压缩文件使用的是DotNetZip(Ionic.Zip.dll), 运行源码需要加入这个库.
优缺点
对比之前的老方法大大节省了构建时间,因为该方法只需构建一次,然后通过脚本修改渠道并签名就可。
但是对于三位数以上的渠道还是有点力不从心,另外该方法需要解压缩、压缩、重签名耗费时间较多,重签名可能会导致apk包在运行时有兼容性问题。
引用
友盟github
maven&gradle打包
原理
都是采用在AndroidManifest.xml的节点中添加如下元素,构建时替换value值得方式。
实现
- Maven
Maven是一个软件项目管理和自动构建工具,配合使用Android-maven-plugin插件,以及maven-resources-plugin插件可以很方便的生成渠道包,下面简要介绍下打包过程,更多Maven以及插件的使用方法请参考相关文档。
首先,在AndroidManifest.xml的节点中添加如下元素,用来定义渠道的来源:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
定义好渠道来源后,接下来就可以在程序启动时读取渠道号了:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
要替换AndroidManifest.xml文件定义的渠道号,还需要在pom.xml文件中配置Resources插件:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
准备工作已经完成,现在需要的就是实际的渠道号了。下面的脚本会遍历渠道列表,逐个替换并打包:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
在前期渠道很少时这种方法还可以接受,但只要渠道稍微增多该方法就不再适用了,原因是每打一个包都要执行一遍构建过程,效率太低。
- gradle
以友盟的渠道统计为例,渠道信息一般在 AndroidManifest.xml中修改以下值:
- 1
- 2
- 3
- 1
- 2
- 3
首先你必须在AndroidManifest.xml中的meta-data修改以下的样子:
- 1
- 2
- 3
- 1
- 2
- 3
其中${UMENG_CHANNEL_VALUE}
中的值就是你在gradle中自定义配置的值。
build.gradle文件就利用productFlavors这样写
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
其中[UMENG_CHANNEL_VALUE: "wandoujia"]
就是对应${UMENG_CHANNEL_VALUE}
的值。
不过现在有个更加简洁的写法
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
在android studio中sync gradle在build下可以看到
直接在gradle中点击assemble
可构建所有渠道的包
单独点击对应渠道的assemble
比如assembleC360
可以单独构建出C360渠道的包
代码中获取渠道值如下代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
优缺点
maven&gradle对于每个渠道都会单独构建一次,比较耗时,但是可以对各个渠道更加细化的定制
样例参考:
Gradle多渠道打包
由于国内Android市场众多渠道,为了统计每个渠道的下载及其它数据统计,就需要我们针对每个渠道单独打包,如果让你打几十个市场的包岂不烦死了,不过有了Gradle,这再也不是事了。 以友盟统计为例,在AndroidManifest.xml里面会有这么一段:
<meta-data
android:name="UMENG_CHANNEL"
android:value="Channel_ID" />
里面的Channel_ID就是渠道标示。我们的目标就是在编译的时候这个值能够自动变化。 * 第一步 在AndroidManifest.xml里配置PlaceHolder
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />
第二步 在build.gradle 设置productFlavors
android {
productFlavors {
xiaomi {}
_360 {}
baidu {}
wandoujia {}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
}
然后直接执行 ./gradlew assembleRelease
然后就等待打包完成吧。
assemble 这个命令,会结合 Build Type 创建自己的task,如:
./gradlew assembleDebug
./gradlew assembleRelease
常用命令如下:(linux下是./gradlew,该脚本在项目下,windows直接gradlew即可)
./gradlew -v 版本号,首次运行,没有gradle的要下载的哦。
./gradlew clean 删除HelloWord/app目录下的build文件夹
./gradlew build 检查依赖并编译打包
这里注意的是 ./gradlew build 命令把debug、release环境的包都打出来,生成的包在目录HelloWord/app/build/outputs/apk/下。如果正式发布只需要打release的包,该怎么办呢,下面介绍一个很有用的命令 assemble, 如
./gradlew assembleDebug 编译并打Debug包
./gradlew assemblexiaomiDebug 编译并打xiaomi的debug包,其他类似
./gradlew assembleRelease 编译并打Release的包
./gradlew assemblexiaomiRelease 编译并打xiaomi的Release包,其他类似
./gradlew installRelease Release模式打包并安装
./gradlew uninstallRelease 卸载Release模式包
http://www.jianshu.com/p/44d40f8e67c9 git自动获取包名打包
360多渠道打包
来源
这个打包方法是由奇虎360的工程师开源出来的,这位大神在github的id是seven456
原理
利用的是Zip文件“可以添加comment(摘要)”的数据结构特点,在文件的末尾写入任意数据,而不用重新解压zip文件(apk文件就是zip文件格式);所以该工具不需要对apk文件解压缩和重新签名即可完成多渠道自动打包,高效速度快,无兼容性问题;
实现方式
- java源码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 使用方法
1、命令行使用说明:
用法:Java -jar MCPTool.jar [-path] [arg] [-contents] [arg] [-password] [arg]
-path APK文件路径
-outdir 输出路径(可选),默认输出到APK文件同一目录
-contents 写入内容集合,多个内容之间用“;”分割,如:googleplay;m360; 当没有“-contents”参数时输出已有文件中的content
-password 加密密钥(可选),长度8位以上,如果没有该参数,不加密
-version 显示版本号
例如:
写入:
java -jar MCPTool.jar -path D:/test.apk -outdir ./ -contents googleplay;m360; -password 12345678
读取:
java -jar MCPTool.jar -path D:/test.apk -password 12345678
2、Android代码中读取写入的渠道号:
导入MCPTool.jar中的MCPTool类,MCPTool.getChannelId(context, mcptoolPassword, defValue)读出写入的渠道号;
3、jenkins、hudson、ant使用说明:
请看MultiChannelPackageTool\build-ant\MCPTool\build.xml文件;
4、Windows下bat脚本运行说明:
拖拽文件即可完成多渠道打包:MultiChannelPackageTool\build-ant\MCPTool\MCPTool.bat;
拖拽文件检查渠道号是否写入成功:MultiChannelPackageTool\build-ant\MCPTool\MCPTool-check.bat;
- 获取渠道号
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 1
优缺点
没有解压缩、压缩、重签名,没有兼容性问题,速度最快;写入的渠道号数据支持加密,安全可靠;
由于速度极快,我还可以作为服务器端下载apk时动态写入“特定数据”,用户下载到apk后安装启动,读取“特定数据”完成特定的操作;
如:加好友功能,下载前写入用户ID,用户下载后启动apk,读取写入的用户ID,完成加好友操作,用户体验大大提升,没有断裂感;
当然,也可以写入JSON数据,想做什么就做什么;
引用
seven456:MultiChannelPackageTool
360多渠道打包升级版:
原理
利用的是Zip文件“可以添加comment(摘要)”的数据结构特点,在文件的末尾写入任意数据,而不用重新解压zip文件(apk文件就是zip文件格式)。
实现
实现方式有三种:Python脚本、Java脚本、gradle构建
- 方法一:python脚本的方式
python源码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
python脚本
python PackerNg.py [file] [market] [output] [-h] [-s] [-t TEST]
方法二:java脚本的方式
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
java脚本
java -jar PackerNg.jar apkFile marketFile outputDir
方法三:gradle构建
在项目top level build.gradle中添加
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
在 app level build.gradle中添加
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
着重几点
- 改善了360多渠道打包方式中api兼容性的问题
ZipFile.getComment是ZIP文件注释写入,使用Java会导致APK文件被破坏,无法安装。这里是读取ZIP文件注释的问题,Java 7里可以使用zipFile.getComment()方法直接读取注释,非常方便。但是Android系统直到API 19,也就是4.4以上的版本才支持 ZipFile.getComment() 方法。由于要兼容之前的版本,所以这个方法也不能使用。改为:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- Android 7.0签名校验引起的安装失败
为了提高Android系统的安全性,Google从Android 7.0开始增加一种新的增强签名模式,从Android Gradle Plugin 2.2.0开始,构建系统在打包应用后签名时默认使用APK signature scheme v2,该模式在原有的签名模式上,增加校验APK的SHA256哈希值,如果签名后对APK作了任何修改,安装时会校验失败,提示没有签名无法安装,使用本工具修改的APK会无法安装,解决办法是在 signingConfigs 里增加 v2SigningEnabled false ,禁用新版签名模式,技术细节请看官方文档:APK signature scheme v2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
优缺点
使用APK注释保存渠道信息和MAGIC字节,从文件末尾读取渠道信息,速度飞快
实现为一个Gradle Plugin,支持定制输出APK的文件名等信息,方便CI集成
提供Java版和Python的独立命令行脚本,不依赖Gradle插件,支持独立使用
缺点
没有使用Android的productFlavors实现,无法利用flavors条件编译的功能
总结
原始多渠道打包:
- 1
- 1
友盟多渠道打包:
- 1
- 2
- 3
- 1
- 2
- 3
360多渠道打包
- 1
- 2
- 3
- 1
- 2
- 3
360多渠道打包plus(进阶版)
- 1
- 1
maven、gradle版
- 1
- 1
那么我们选择时可以按实际情况使用360多渠道打包plus,或者android studio gradle多渠道打包。需注意的是360多渠道打包plus无法通过android7.0签名校验,当然只要是通过后期修改apk文件的方式都不能通过android7.0的签名校验。
这篇关于关于多渠道打包的最强攻略--总结版的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!