jblzg的技术园

关注基于.Net的Web解决方案,高性能数据库设计,高性能Web服务解决方案,关注移动开发

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  22 随笔 :: 0 文章 :: 356 评论 :: 11万 阅读
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

2011年11月23日

前言

我写Android 刚不久,发现一个Android应用是否有更多人用,不仅取决于应用本身,还取决于应用的推广,在中国,起码就有以下十个市场需要推广:360开放平台、爱米吧、谷歌电子市场、安智市场、应用汇、优亿市场、机锋、安卓市场、N多、安卓星空。

为了衡量每个市场的效果,我使用了友盟的分发渠道分析接口,只需要为不同的市场在 AndroidManifest.xml 里定义不同的 meta-data UMENG_CHANNEL 值,然后为各市场分发各自的apk即可。

这时问题就来了,如果我的应用有更新,如果没有一个自动化的方法,我需要用eclipse手动export、签名…… ,光敲签名时的storepass和keypass就够受的了,更不用说还得每次记得修改签名文件代表不同市场的后缀,比如MyApp_360.apk、MyApp_androidmarket.apk……,非常容易出错,也很浪费时间。

于是我花了1天的时间,用powershell脚本将上面的操作自动化了,感觉很棒,和大家分享一下,希望能够帮到各位。

在阅读这篇文章之前,我假设您已经知道如何给Android 应用签名,了解apache ant,已经集成了友盟分发渠道分析接口,了解PowerShell。

实现思路

  1. 用PowerShell实现一个方法:使用ant自动编译项目,在每次编译之前,修改 AndroidManifest.xml 中meta-data UMENG_CHANNEL 的值为指定市场的标识。
  2. 用字符串数组存储所有市场的标识,遍历该数组,遍历至每个元素时,都将该元素传入上面的方法,可实现针对不同的市场进行编译,编译完成后,再对编译好的应用签名即可。

系统环境

  • Windows 7 Untimate
  • JDK 7 Update1,假设路径为: E:\Program Files\Java\jdk1.7.0_01
  • apache-ant-1.8.2,假设路径为:E:\Program Files\apache-ant-1.8.2
  • Android SDK,假设路径为:E:\Program Files\Android\android-sdk

用ant自动编译项目

  • 假设Android项目路径为:D:\workspace\MyApp
  • 检查是否存在文件D:\workspace\MyApp\build.xml,这是使用ant编译项目时需要用到的配置文件
    • 若不存在,在command窗口中执行:
      • CD D:\workspace\MyApp
      • D:
      • "E:\Program Files\Android\android-sdk\tools\android" update project --path .
    • 若存在或通过上面的步骤生成了build.xml,修改文件中<project name="xxx" default="help"> xxx为自己项目的名称(项目名称如何改,参见文末的更新),如:<project name="MyApp" default="help">
  • 新建批处理文件D:\workspace\MyApp\build.bat,该文件使用ant对android项目自动编译,文件内容如下,请根据自己项目、系统的实际情况修改路径
1 SET JAVA_HOME=E:\Program Files\Java\jdk1.7.0_01
2 cd D:\workspace\MyApp
3 D:
4 "E:\Program Files\apache-ant-1.8.2\bin\ant" release

如果系统环境没问题,build.bat执行后,在目录 D:\workspace\MyApp\bin 中应该可以看到编译好的MyApp-release-unsigned.apk。

注意:如果项目中有引用的第三方jar包类库,要把这些类库放到项目根目录的 "libs" 目录下,否则,ant在编译的时候会出错。

流程详解

1、定义参数

1 param($ProjectName$ProjectRootDirectory$KeystorePath$StorePass$KeyPass$Alias)
2 
3 $channels = @("360""aimi8""anzhi""appchina""eoemarket""gfan""hiapk""nduoa""starandroid")
4 $defaultChannel = "androidmarket"
5 $jdkPath = "E:\Program Files\Java\jdk1.7.0_01"
6 $androidSDKPath = "E:\Program Files\Android\android-sdk"
7 $signedPath = "$ProjectRootDirectory\bin\signed"
8 $zipalignedPath = "$ProjectRootDirectory\bin\zipaligned"
  • $ProjectName:项目名称,如:MyApp
  • $ProjectRootDirectory:项目路径,如:D:\workspace\MyApp
  • $KeystorePath:keystore路径,如:D:\workspace\MyApp\keystore
  • $StorePass:store password,如:123456
  • $KeyPass: key password,如:123456
  • $Alias: keystore alias,如:MyApp
  • $channels:定义了除AndroidManifest.xml中定义的默认市场标识外,剩下的所有市场标识
  • $defaultChannel:即上面提到的默认市场标识,为什么要有默认市场标识的原因是,我们的AndroidManifest.xml文件不会常改,我们也不希望每次自动编译、签名完毕后,看到这个文件处于被修改的状态,所以我设计在最后才给默认的市场编译,这样的话,前面修改了n次的AndroidManifest.xml在最后回到未修改的状态
  • $signedPath:即签好名的apk文件存储路径
  • $zipalignedPath:即zipalign优化后文件存储路径,最后要发布的也是这个目录下的apk文件

2、修改 AndroidManifest.xml

1 $manifestPath = "$ProjectRootDirectory\AndroidManifest.xml"
2 $FILE = [System.IO.File]::ReadAllText($manifestPath)
3 $FILE = [REGEX]::replace($FILE, '<meta-data\r?\n?\s+android:name="UMENG_CHANNEL"\r?\n?\s+(.*?)>', '<meta-data
4             android:name="UMENG_CHANNEL"
5             android:value="' + $ChannelName + '" />', [Text.regularexpressions.regexoptions]::SingleLine)
6 [System.IO.File]::WriteAllText($manifestPath$FILE)

$ChannelName 代表每次遍历传入的市场标识,如:anzhi

3、调用 build.bat 编译 项目

1 & "$ProjectRootDirectory\build"

4、为编译好的应用签名

1 & "$jdkPath\bin\jarsigner" -keystore $KeystorePath -storepass $StorePass -keypass $KeyPass -signedjar "$signedPath\$ProjectName-$ChannelName.apk" -verbose "$ProjectRootDirectory\bin\$ProjectName-release-unsigned.apk" $Alias -digestalg SHA1 -sigalg MD5withRSA 

  • 注意最后2个参数:-digestalg SHA1 -sigalg MD5withRSA,如果你当前的环境是 JDK 7,一定要加上这两个参数,否则签名完毕的应用在安装时会有错误:Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES] [1]
  • 签好名的应用在 $signedPath 定义的路径中

5、zipalign优化签好名的apk

1 if (Test-Path -path "$zipalignedPath\$ProjectName-$ChannelName.apk") {
2     Remove-Item "$zipalignedPath\$ProjectName-$ChannelName.apk"
3 }
4     
5 & "$androidSDKPath\tools\zipalign" -v 4 "$signedPath\$ProjectName-$ChannelName.apk" "$zipalignedPath\$ProjectName-$ChannelName.apk"

6、批处理调用powershell脚本,实现自动化编译、签名

假设powershell脚本存储于:D:\workspace\build4DifferentChannels.ps1,新建批处理脚本:D:\workspace\build4DifferentChannels_MyApp.bat:

1 powershell D:\workspace\build4DifferentChannels.ps1 MyApp "D:\workspace\MyApp" "D:\workspace\MyApp\keystore" 123456 123456 myapp

用批处理调用powershell脚本build4DifferentChannels.ps1,并传入了之前定义的各个参数。以后需要发布应用时,就执行该批处理,自动为各个市场编译、签名应用即可,十分方便。

如果执行改脚本遇到错误:

    File D:\workspace\build4DifferentChannels.ps1 cannot be loaded because the execution of scripts is disabled on this system. 

就用管理员权限打开command窗口,执行下面的命令:

1 powershell
2 Set-ExecutionPolicy RemoteSigned 

7、完整脚本下载

build4DifferentChannels_20111209.zip

参考 

[1]:http://code.google.com/p/android/issues/detail?id=19567

[2]:http://www.androidengineer.com/2010/06/using-ant-to-automate-building-android.html

广告

给最近开发的两个应用打一下广告

更新 

  • 2011-11-28
    谢谢wanx的提醒:<project name="xxx" default="help">,这里的xxx不是随便写,而是和使用eclipse手动编译出来的apk文件名一致,如果eclipse编译的文件名是Abc.apk,那么build.xml这段就应该改为:<project name="Abc" default="help"> 
  • 2011-12-02
    再次谢谢wanx的提醒:如果项目中有引用的第三方jar包类库,要把这些类库放到项目根目录的 "libs" 目录下,否则,ant在编译的时候会出错。
  • 2011-12-07
    加入zipalign优化脚本
  • 2011-12-09
    在zipalign之前,先删除旧有apk文件
posted @ 2011-11-23 19:44 jblzg 阅读(3084) 评论(7) 推荐(8) 编辑

2011年7月6日

摘要: JSON与Protocol Buffers同为序列化数据的存储格式。性能比较,视平台、语言、数据结构复杂程度的不同,Protocol Buffers与JSON相比,性能可能会从慢15倍到快5倍。值得指出的是,在Android系统中,Protocol Buffers反序列化数据会比JSON快大约3倍。 阅读全文
posted @ 2011-07-06 09:44 jblzg 阅读(4687) 评论(2) 推荐(0) 编辑

2010年4月16日

摘要: 时间往往在不经意间就浪费掉了,比如我们在寻找上一个光标位置的时候,好好学习并利用下面的技巧,会提高工作效率,减少不必要浪费的时间,提高时间利用率,让生活更加美好。 阅读全文
posted @ 2010-04-16 17:58 jblzg 阅读(3919) 评论(2) 推荐(2) 编辑

2010年3月5日

摘要: 批处理获得任意天前的日期 阅读全文
posted @ 2010-03-05 17:19 jblzg 阅读(2007) 评论(0) 推荐(0) 编辑

2010年3月2日

摘要: SQLServer2008中如何收缩日志文件,在邀月工作室的日志《SQL2008如何压缩日志(log)文件?》已经详细描述,这里不再赘述。本文的重点是与大家分享日志截断、收缩后,物理文件的尺寸依然没有减小到期望尺寸的问题。 阅读全文
posted @ 2010-03-02 18:01 jblzg 阅读(8595) 评论(3) 推荐(0) 编辑

2009年11月20日

摘要: 今天凌晨(20091120)2:05左右,与Chrome技术交流QQ群(75448027)的朋友们一起聆听了远在美国的ChromeOS发布会,经过一番实验后,终于在自己PC的虚拟机中成功运行了ChromeOS。这篇文章旨在帮助所有对ChromeOS感兴趣的朋友一起实际体验一下ChromeOS,比看截图要更有趣一些。 阅读全文
posted @ 2009-11-20 16:14 jblzg 阅读(17347) 评论(38) 推荐(3) 编辑

2009年9月14日

摘要: ReadWriteWeb最近推出了系列文章:“2009年互联网5大趋势”,第一个主要的趋势是结构化的数据,这个概念在以往有关语义网(Semantic Web)的一些演讲中,曾被引用过,但显而易见,到现在为止,结构化的数据比语义网的发展趋势更加明显。本文会分析结构化的数据在今年的发展,并且有三个产品供参考:OpenCalais, Google, Wolfram Alpha。 阅读全文
posted @ 2009-09-14 00:45 jblzg 阅读(5500) 评论(10) 推荐(5) 编辑

2009年9月6日

摘要: 我写本文的目的,是和各位分享一下内容篡改式攻击的判断方法、SQL注入攻击的防范、以及被攻击后的补救(数据恢复)相关知识,如有谬误,期待您的指正。 * 如何在IIS6中安装WebKnight? * 如何配置WebKnight * 如何恢复被篡改的数据 * 如何找到有漏洞的程序 阅读全文
posted @ 2009-09-06 23:14 jblzg 阅读(7497) 评论(45) 推荐(1) 编辑

2009年6月6日

摘要: 继去年参加了Google Developer Day 2008后,又迎来了Google Developer Day 2009,谢谢公司给我的时间,得以如愿参加这个技术盛宴。 技术的发展,往往迅雷不及掩耳。记得去年的GDD,谈到了云计算这个概念,经过了1年的发展,云计算的概念已经深入人心。去年谈到的App Engine、Google Maps API、Open Social、Android、iGoogle、Google Web Toolkit今年都有讲,这些技术都已经得到了更进一步的发展。值得注意的是,去年谈到的Gears,今年只字未提,这是因为今年的新技术:HTML5 其实已经可以替代Gears了。今年的重头戏是Google Wave,我知道最近在美国举行的2009 Google I/O大会上公布的Google Wave引起轰动,据说这是可以媲美Email发明的里程碑式的通讯工具。 阅读全文
posted @ 2009-06-06 02:46 jblzg 阅读(5523) 评论(33) 推荐(0) 编辑

2009年3月4日

摘要: 一个服务ServiceA每5分钟会对配置好的网站首页、频道首页源地址分别发起一次请求,然后把请求的数据写入一个Html文档,这个Html文档即静态化的页面。 本来一直工作的很正常,但今天我使用了自定义的500错误页面后出问题了,首页静态页面不定时地呈现出了我自定义的500错误页面,经分析,发现原来没有使用自定义错误页面时,WebResponse的返回结果是一个错误,可以被捕捉到;但使用了自定义错误页面后,WebResponse就把这个错误页面当成了首页的内容了。 阅读全文
posted @ 2009-03-04 18:24 jblzg 阅读(1169) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示