在国内Android常用渠道可能多达几十个,如: 
谷歌市场、腾讯应用宝、百度手机助手、91手机商城、360应用平台、豌豆荚、安卓市场、小米、魅族商店、oppo手机、联想乐商、中兴汇天地、华为、安智、应用汇、木蚂蚁、3G安卓市场(久邦开发者发布系统) 
uc应用商店、苏宁应用、淘宝手机助手、蘑菇市场、搜狗市场、搜狗助手、机锋、易用汇(金立手机)、中国联通沃商、中国移动MM、中国电信天翼、亿优市场、历趣世界、冒泡堂、网讯安卓开发者平台、桌乐、网易、泡椒网、十字猫、酷传、安粉、安卓园、安卓之家 
所以在工作中,当项目开发、测试完毕后就需要针对不同的渠道打出对应的apk安装包。为了统计每个渠道效果,我们可以使用Umeng sdk或者百度的sdk。这些sdk的使用我就不再这里赘述了,请看相应的开发文档即可。本文以友盟统计为例。

批量打包方式一:Gradle方式

我相信现在应该很多开发环境都是AndroidStudio了,对Gradle相对还是熟悉的。如果您使用的是Eclipse也没有关系,用AndroidStudio导入Eclipse工程,或者把gradle配置放在Eclipse工程下(因为AndroidStudio和Eclipse的工程目录有些差别,把对应的目录配置对即可) 
首先我们使用AndroidStudio新建一个工程,名叫AndroidBatchApk,工程结构如下: 
打开AndroidManifest.xml文件 添加友盟的渠道配置如下:

在MainActivity 显示渠道名代码:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MainActivity</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AppCompatActivity</span> {</span><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCreate</span>(Bundle savedInstanceState) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState);setContentView(R.layout.activity_main);String channel = ManifestUtil.getMetaDataFromAppication(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"UMENG_CHANNEL"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//String channel = ManifestUtil.getUmengChannel(this);</span>((TextView) findViewById(R.id.tv_channel)).setText(channel);}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>
<code class="hljs haskell has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><meta-<span class="hljs-typedef" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">data</span></span>android:name=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"UMENG_APPKEY"</span>android:value=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Your UMENG_APPKEY"</span> /><meta-<span class="hljs-typedef" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">data</span></span>android:name=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"UMENG_CHANNEL"</span>android:value=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"${UMENG_CHANNEL_VALUE}"</span> /> //${<span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">UMENG_CHANNEL_VALUE</span>}是个占位符</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>
 打开app目录下的build.gradle文件,修改成如下形式:
<code class="hljs livecodeserver has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">apply plugin: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'com.android.application'</span>android {compileSdkVersion <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">22</span>buildToolsVersion <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"22.0.1"</span>packagingOptions {exclude <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'META-INF/NOTICE.txt'</span>exclude <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'META-INF/LICENSE.txt'</span>}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //签名</span>signingConfigs {release {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //storeFile file("../yourapp.keystore")</span>storeFile <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">file</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"keystore_apk.jks"</span>)storePassword <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123456"</span>keyAlias <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"apk"</span>keyPassword <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123456"</span>}}buildTypes {release {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> // 不显示Log</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //buildConfigField "boolean", "LOG_DEBUG", "false"</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //minifyEnabled true //混淆</span>zipAlignEnabled <span class="hljs-constant" style="box-sizing: border-box;">true</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //内存对齐</span>shrinkResources <span class="hljs-constant" style="box-sizing: border-box;">true</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //移除无用的resource文件</span>proguardFiles getDefaultProguardFile(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'proguard-android.txt'</span>), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'proguard-rules.pro'</span>signingConfig signingConfigs.releaseandroid.applicationVariants.all { variant ->def stringsFile = <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">new</span> File(variant.outputs[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>].processResources.assetsDir, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"abc.txt"</span>)stringsFile.mkdir()}applicationVariants.all { variant ->variant.outputs.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">each</span> { output ->def outputFile = output.outputFile<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (outputFile != <span class="hljs-constant" style="box-sizing: border-box;">null</span> && outputFile.name.endsWith(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'.apk'</span>)) {def fileName = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"APK_${releaseTime()}_${variant.productFlavors[0].name}.apk"</span>output.outputFile = <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">new</span> File(outputFile.parent, fileName)}}}}}lintOptions {checkReleaseBuilds <span class="hljs-constant" style="box-sizing: border-box;">false</span>abortOnError <span class="hljs-constant" style="box-sizing: border-box;">false</span>ignoreWarnings <span class="hljs-constant" style="box-sizing: border-box;">true</span>}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> // 渠道列表</span>productFlavors {<span class="hljs-title" style="box-sizing: border-box;">_360</span> {}<span class="hljs-title" style="box-sizing: border-box;">_91</span> {}QQ {}appChina {}baidu {}google {}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"> //.....</span>}productFlavors.all { flavor ->flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]}}def releaseTime() {<span class="hljs-constant" style="box-sizing: border-box;">return</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">new</span> Date().<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">format</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"yyyy-MM-dd HH-mm-ss"</span>, TimeZone.getTimeZone(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"GMT+8"</span>))}dependencies {compile fileTree(dir: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'libs'</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">include</span>: [<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'*.jar'</span>])compile <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'com.android.support:appcompat-v7:22.2.1'</span>}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li></ul>

上面的配置,我们测试打6个包,分别是google 、_360、 _91、 appChina、 QQ、 baidu

打开cmd命令行 进入工程所在的目录,输入命令:gradle build 不出意外将看到如下成功界面: 

并且在output目录下生成了我们要的apk包(AndroidBatchApk\app\build\outputs\apk) 

现在用的安装我们的生成apk文件,安装google渠道的apk。 

到这里我们就通过gradle方式成功的批量打包了,

时间我们只花费了25秒,但是这是最简单的工程,如果是实际的开发中,我们的项目会很大,打包的时间也会花费很长时间,我现在公司的项目,通过这种方式打包,需要30、40分钟左右,这也是挺长的。时间上并不占优势。但是比我们用工具一个个的打apk强太多了。下面为大家界面一种更高效的打包方式。

批量打包方式二:Python批量打包

首先配置好Python,我用的是Python2.7版本。使用该方式,不把渠道名称放在AndroidManifest.xml 里,而是新建一个空文件,文件名就是渠道名称。该文件放在apk目录的META-INF里。META-INF目录下默认文件列表如下: 

现在我们要解决两个问题:

如果在META-INF目录下新建文件?

我们解决第一个问题。首先我们通过AndroidStudio或者Eclipse打一个正式环境的apk安装包,不需要有渠道。 
然后按照渠道列表 复制出各个渠道的,然后往apk文件里写入文件为渠道名的空文件。我们使用Python代码来实现该功能,代码如下:

<code class="hljs python has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> sys,os,shutil,zipfile,time
apkVersion=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"1.0"</span>
srcFileName=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"source.apk"</span>
destDir=os.path.abspath(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'.'</span>)
file=open(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"channel.txt"</span>)<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">writeChannelToApk</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(filename,channel)</span>:</span>z=zipfile.ZipFile(filename,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'a'</span>,zipfile.ZIP_DEFLATED)empty_channel_file=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"META-INF/channel_{channe}"</span>.format(channe=channel)target_file=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"channel.apk"</span>z.write(target_file,empty_channel_file)z.close()<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"writeChannelToApkchannel"</span>+channel+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">","</span>+filename+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\n"</span><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">cpFile</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(srcPath,fileName)</span>:</span>destPath = destDir + os.path.sep + fileName<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> os.path.exists(srcPath) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">and</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">not</span> os.path.exists(destPath):shutil.copy(srcPath,destPath)<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">not</span> os.path.exists(srcFileName):<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"sourcefile"</span>+srcFileName+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"notexists"</span>sys.exit(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)start = time.clock()<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> line <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> file:channel=line.strip(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\n'</span>).strip()targetFileName=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"apk_"</span>+channel+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"-"</span>+apkVersion+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">".apk"</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"copyfile:"</span>+targetFileNamecpFile(srcFileName,targetFileName)writeChannelToApk(targetFileName,channel)
end = time.clock()print(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"The function run time is : %.03f seconds"</span> %(end-start))</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li></ul>

上面是我编写的Python代码,根据代码我们需要三个文件,一个我们打出的apk文件(source.apk 当然名字可以改)、一个空apk文件(channel.apk)和渠道列表文件(channel.txt) 目录如下: 

渠道文件内容如下: 
360 
appChina 
wandoujia 
91 
baidu 
QQ 
3G 
eoe 
anzhi 
163 
hiapk 
jifeng 
xiaomi 
meizu 
oppo 
lenovo

在命令行输入:python batch_apk.py 回车

瞬间完成: 

解压文件oppo渠道的apk,看看是不是META-INF下是不是有渠道文件: 

如果读取META-INF下的渠道文件?

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ManifestUtil</span> {</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> String channel;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> String <span class="hljs-title" style="box-sizing: border-box;">getUmengChannel</span>(Context context) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//return getMetaDataFromAppication(context, "UMENG_CHANNEL");</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> getChannel(context);}<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*** 获取META-INFO下面的渠道*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> context*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @return</span>*/</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> String <span class="hljs-title" style="box-sizing: border-box;">getChannel</span>(Context context) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!TextUtils.isEmpty(channel)) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> channel;}ApplicationInfo appinfo = context.getApplicationInfo();String sourceDir = appinfo.sourceDir;ZipFile zipfile = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> String start_flag = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"META-INF/channel_"</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {zipfile = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ZipFile(sourceDir);Enumeration<?> entries = zipfile.entries();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (entries.hasMoreElements()) {ZipEntry entry = ((ZipEntry) entries.nextElement());String entryName = entry.getName();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (entryName.contains(start_flag)) {channel = entryName.replaceAll(start_flag, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> channel;}}} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (IOException e) {e.printStackTrace();} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span> {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (zipfile != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {zipfile.close();} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (IOException e) {e.printStackTrace();}}}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>;}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li></ul>

我们安装oppo渠道的apk看看能否读取到渠道名: 

通过上面的对比,使用Pyhon往META-INF写入渠道的方式,比gradle方式极大的提高了效率。

资源下载 
Have Fun !

Android批量打包-如何一秒内打几十个apk渠道包相关推荐

  1. Android批量打包 如何一秒内打完几百个apk渠道包

    在国内Android常用渠道可能多达几十个,如:  谷歌市场.腾讯应用宝.百度手机助手.91手机商城.360应用平台.豌豆荚.安卓市场.小米.魅族商店.oppo手机.联想乐商.中兴汇天地.华为.安智. ...

  2. Android 批量打包 基于Walle的多渠道快速打包自动脚本

    Android 批量打包 基于Walle的多渠道快速打包自动脚本 Android Signature V2 Scheme签名下的新一代渠道包打包神器 github主页:https://github.c ...

  3. java实现Android一键打包,秒秒钟生成上百个渠道包

    要实现java一键生成渠道包功能,事先我们需要做好准备工作,大概有以下3点 1.准备好所以需要生成的渠道号放在excel文档中 2.需要下载两个jar包,commons-compress-1.16.1 ...

  4. php动态生成apk渠道包,Android自动生成渠道包

    承接上文Android应用的自动化构建,我们已经通过ANT自动构建了应用,那接下来的问题是,如何自动构建渠道包,这里强烈推荐一篇文章美团Android自动化之旅-生成渠道包. 美团提到的第三种方式,截 ...

  5. android ant批量打包

    当我们对安卓项目需要分很多渠道打包的时候,批量打包工具无疑是个不二选择,批量打包的方式大概可以分为两种,第一是通过第三方的打包平台,比如360加固宝,这确实是个很好的工具,既提高了源代码的安全性能,又 ...

  6. android 渠道包测试,Android快速批量多渠道包的“蛋生”

    对于安卓程序猿朋友来说,每当发布新版本的APP,均会分发到各大应用市场,比如腾讯应用宝,豌豆荚和360手机助手等.为了让程序猿同志们更好的区分不同的应用市场,掌握各市场APP发展状况,为了更多体现世界 ...

  7. android 自定义apk名,Android Studio 打包自定义apk文件名

    使用Android Studio打包的时候,我们有时候需要自定义apk的文件名,在此记录一下. 在app的build.gradle中,根节点下使用关键词def声明一个全局变量,用于获取打包的时间,格式 ...

  8. 使用Ant 实现批量打包Android应用

    2019独角兽企业重金招聘Python工程师标准>>> 由于公司运维需要以及应用中需要加上应用推广的统计,往往要对应二三十个渠道,按照正常方法一个一个的去生成不同渠道包的应用,不仅浪 ...

  9. ant 实现批量打包android应用

    很多的应用中需要加上应用推广的统计,如果一个一个的去生成不同渠道包的应用,效率低不说,还有可能不小心弄错了分发渠道,使用ant可以批量生成应用. 一.添加渠道包信息 为了统计渠道信息,就不得不在程序的 ...

  10. android打包工具多渠道批量打包,Android 快速渠道批量打包详解教程-美团多渠道打包方案...

    今天写一篇文章来总结下android批量打渠道包美团版本.之前项目上一直用的是gradle 批量打包方式,那个速度啊真是令人发指,15个渠道得跑上半个小时,出去吃顿饭回来,还在跑.特别是赶上项目上线的 ...

最新文章

  1. linux 网络编程 ping,Linux 网络编程基础(4) -- Ping 的C代码实现
  2. splunk的统计分析功能——特定字段的统计功能包括取值分布(+topK,min/max/平均值)...
  3. IE弹出窗口显示URL地址栏
  4. 第三次学JAVA再学不好就吃翔(part27)--自定义工具类
  5. java linq_LINQ和Java
  6. 7 centos 查看程序文件数量_解析CentOS 7中系统文件与目录管理
  7. centos中安装配置nginx完成之后主机无法访问
  8. 支付宝APP支付里设置应用网关和授权回调地址是不必填的
  9. 02-C#(基础)基本的定义和说明
  10. python discover()没有加载测试用例_Python系统学习 - Unittest
  11. 编译安装wpa_supplicant
  12. 修改U盘、移动硬盘时提示目标文件夹访问被拒绝的问题解决思路
  13. 2007五一[西北行] - 第二天:延安(窑洞,杨家岭,宝塔山...)
  14. 征途服务器 文件夹需手,手游新征途手工架设服务端+配套双客户端+架设流程+服务器部署文档等...
  15. maven3实战之仓库
  16. 华为GAUSS数据库常用的单行操作函数介绍
  17. 坚挺市场下,ICT企业如何赢盈并重持续增长–2022年B2B企业新增长趋势之ICT篇
  18. 【数学】泰勒公式推导(佩亚诺余项)
  19. 使用PLAN法提升执行力——笔记与答案
  20. Oracle OCA与OCP认证考试途径

热门文章

  1. oracle建索引时报ora00955 名称已由现有对象使用,关于处理ORA-00955: 名称已被现有对象占用的错误...
  2. css 3d环形,CSS3 飞行的3D圆环
  3. Unity3d FingerGestures
  4. BZOJ2827 千山鸟飞绝
  5. PHP对接苹果支付全流程
  6. 21届校招中获得12家公司offer的一些经验(包括6家银行信息科技岗offer)
  7. 新概念英语第三册21-40课(转)
  8. win7系统文件夹共享后有锁图标怎么去掉?
  9. BinaryFormatter serialization and deserialization are disabled within this application
  10. Windows 7 通用 CDC 串口驱动程序