在过去的一两年里,通过反编译一些比较知名的创业公司的早期产品,包括脸萌,两鲜等产品以及面试了好多有几年开发经验的开发者,发现其实很多产品的发布都是由开发者在自己的eclipse或者as打包的,这样有一些风险实际上就留给公司了,比如代码可能没有混淆,apk签名是eclipse debug签名,另外开发者机器编译的sdk是否是发布需要的等等一系列问题。对于笔者之前所在的公司来说,这些都不是问题,因为他们会将所有产品构建包括日常测试的版本构建都交给后台处理,形成一套自动化编译的体系。
本人一直认为想要搭建一个系统首先要了解其大致的工作原理,对于android应用的构建流程要有基本的了解,大体上可以分为如下几个:
为了能尽快的打造出一个每日构建体系,这里介绍了现在用的比较广泛的编译工具 ant,除了能编译出apk,我在搭建这个编译系统的时候还希望做到几点:
1.轻量,少占用资源,存储空间
2.自动化,定时自动拉取最新代码进行编译,兼容手动触发的功能
3.安全,签名信息,编译环境选项与代码隔离
4.易迁移,整体打包迁移方便
5.版本管理采用日期+构建号的方式构成
6.调试版本和发布版本同时生成
7.构建日志及混淆日志需要保存
8.对外发布时能手动生成渠道包
再回头看看我们的大标题看似及其复杂的一个大问题已经被我切割得非常细致了,所以任何一个问题都应该想清楚再动手做,这样目标明确再动手,想必细节实现只是时间长短的问题啦,先看看我们有哪些现成的资源可以利用吧
1.利用sdk中的ant编译脚本build.xml中的release和debug命令,可以编译出响应的版本
2.利用linux自带的crontab可以设置定时任务
3.签名文件,各个配置文件可以放到服务器上
如此看来其实要做的东西也不算太多啦啊那基本可以抽象为预构建,构建和构建后操作
于是就有了这样一个总的构建任务:
<target name="buildAll" depends="clean"> <antcall target="pre-build-all"/> <antcall target="debug"/> <antcall target="post-build-debug"/> <antcall target="release"/> <antcall target="post-build-all"/> </target>
那么我们在预构建的时候需要做的事情呢?结合我们的构建目标可以看到
在不考虑渠道包的情况下,我们只需要替换我们的版本号就可以了,版本采用的是yymmdd日期+构建号的方式,构建号会作为变量存储在一个文件里面,每次构建取出后+1并保存,这样预构建的工作就完成啦
构建后操作主要就两点:
1.分别将debug版本和release版本以及混淆日志复制到输出目录下,按各自规范命名
2.将构建日志输出到日志目录下
将设置环境变量,拉取代码,取构建号等功能串联起来就是这样的,
用shell脚本可以这样写:
export xxx_BN=$((xxx_ANDROID_BN+1))
sed -i"1c xxx_ANDROID_BN=$BN" BN
echo "=====build start for xxx_BN:$xxx_BN====="
PROJECT=xxx
rm $PROJECT/-rf
svn co svn://xxx $PROJECT
cd $PROJECT
ant -buildfile$PROJECT/build.xml buildAll
echo "====build end====="
这个构建的基本功能实现之后,再将这个脚本添加到crontab定时任务里面,这样就可以完成定时启动啦
接下来我们看看渠道包是怎么来生成的,从现在市面上主流的做法来看一般分为三种方案:
1.构建前替换渠道
2.基于反编译替换渠道
3.直接解压内置渠道文件
由于我们用的是友盟sdk,所以渠道号是写在manifest里面的,那么第三种肯定不能用啦,
而第一种方案又太慢了一点,所以选择第二种作为实现方案
反编译方案的shell脚本基本如下:
KEY_STORE_PATH=/key-stores/xxx_release.keystore
for channel in'YYB''360''WDJ''BD'
do
echo"====DELETE BUILD===="
rm -rf build
#cd /channel
echo"====CD PATH===="
cd /channel
echo"====DECODE APK:" +$1 + "===="
java -jar ./apktool.jar d $1 build
echo"====REPLACE Channel ID WITH " + $channel
sed -i's/Channel ID/'$channel'/' build/AndroidManifest.xml
echo"====BUILD APK===="
java -jar ./apktool.jar b build xxx_unsigned.apk
echo"====SIGN APK===="
jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore$KEY_STORE_PATH -storepass xxx -signedjar${1/.apk/_CH_$channel.apk} xxx_unsigned.apk xxx -keypass xxx
done
这里要注意的是使用android 6.0 sdk编译出来的版本用apktool1.5是无法进行反编译的,需要替换到apktool2.0,但是2.0的一些参数有些不一样(这里贴出来的是老代码),具体可以查看一下这个文档 http://ibotpeaches.github.io/Apktool/documentation/
至此,所有的任务都完成啦,整套的构建系统就搭建完成啦,将ant,sdk,构建脚本,签名文件,反编译工具,构建号记录文件通通放到一个目录下,这个系统就可以在任意的linux系统上运行,需要配置的仅仅是java,crontab,输出目录和日志目录
将这个系统的输出目录和脚本触发web化之后,加上权限管理,整个系统就比较方便完善啦