您的位置:首页 > 其它

利用jenkins+ant实现编译前修改文件和批量打包签名

2014-08-10 11:30 573 查看
背景:测试框架通过instrumentation来测试不同的应用,通过AndroidManifest.xml中的
<instrumentation
        android:name=".TargetInstrumentation"
        android:targetPackage="com.example.launcher" >
    </instrumentation>


来与被测应用建立联系。每次打包时都需要修改AndroidManifest.xml文件中instrumentation对应的包名,并引用不同的keystore和密码来签名(只有当测试框架与被测应用签名相同时,才能使用instrumentation)。这个过程本身就易出错,而且由于引入了代码混淆,变得更加痛苦地漫长。现在利用jenkins+ant将整个过程实现了自动化,真是省了好大辛苦。



这个过程自动化的关键在于:

1、ant提供了编译前修改文件的语法

2、SDK中提供的ant build.xml包含了极其完备的编译过程脚本代码,随意修改实现个性化编译

3、 jenkins强大的自动构建和持续集成功能

首先是如何利用ant来修改AndroidManifest.xml文件。ant提供了两个指令用于编译时修改文件,好处就不说了 ,就说说如何使用吧。replaceregexp 和 replace的区别就和java中String replace和replaceAll一样 ,一个支持正则一个不支持。看例子:


<replaceregexp file="${manifest.file}" 
<span style="white-space:pre">	</span>match="android:name=".identify.RunTestScript" 
<span style="font-family: Simsun;"><span style="white-space:pre">	</span>android:targetPackage="w+([-+.]w+)*"" </span>
<span style="font-family: Simsun;"><span style="white-space:pre">	</span>replace="android:name=".RunTestScript" </span>
<span style="font-family: Simsun;"><span style="white-space:pre">	</span>android:targetPackage="${package_name}"" /> </span>


就是将manifest.file(即AndroidManifest.xml文件)中的android:targetPackage的值替换成自己定义的package_name。

这里顺便推荐一个很好的网站,你想要的正则表达式基本上都能在里面找到:点击打开链接



关于build.xml,网上提供了很多版本,大同小异。但别妄想拿来就能用,有够你调的。与其辛辛苦苦调试不知网上什么人写的代码 ,为什么不用官方提供的build.xml呢?在sdk/tools/ant目录下。

对自己的项目添加ant后,将官方build.xml的所有属性及节点复制到自己的build.xml中即可。注意修改version为custom并注释掉导入官方build.xml的那一句。具体操作见jenkins环境搭建的知识库分享。

将修改 AndroidManifest.xml的target加入build.xml。现在还没完事,打包签名也需要修改build.xml.



要想最后打出签名后的包,先修改project属性为release:

<project name="XXX" default="release">


官方build.xml默认的签名是key.store存在而密码手动输入。有手动输入就不叫自动化了,这个需要修改要求手动输密码的target,将这一步注释掉即可:

<target name="-release-prompt-for-password" if="has.keystore">

        <!-- <input
                message="Please enter keystore password (store:${key.store}):"
                addproperty="key.store.password" />
        <input
                message="Please enter password for alias "${key.alias}":"
                addproperty="key.alias.password" /> -->
    </target>


然后在属性里对key.store和key.store.password都赋值即可。

还有一个小问题,如果自动打包,打包的频率是比手工高很多的。那怎么区分每个版本的包呢?这时就可以利用ant自动产生版本号,再修改AndroidManifest.xml中的版本号。对于版本号主流的做法是这样:

versionCode=1 从1开始,每次release增加1

versionName=1.0.1 分两部分,1.0为大版本号,由开发者自己定义;后面跟的build号与versionCode相同

这个过程显然也可以自动化。不过要实现版本号的自增操作需要在工程根目录下添加一个version.properties文件,内容:

app.version.code=1
app.version.major=1.0.
app.version.minor=1


然后再build.xml文件里增加对版本号处理的target:

<target name="increase-version">
        <!-- <propertyfile file="version.properties">
            <entry key="app.version.code" type="int" operation="+" value="1" />
            <entry key="app.version.minor" type="int" operation="+" value="1" />
        </propertyfile> -->
        <property file="version.properties" />
        <echo>Version code: ${app.version.code}</echo>
        <echo>Version name: ${app.version.major}${app.version.minor}</echo>
        
        <property name="match.end" value=""" />
        
        <property name="matchVersionCode.start" value="android:versionCode="" />
        <replaceregexp file="AndroidManifest.xml" match="${matchVersionCode.start}[^"]*${match.end}" replace="${matchVersionCode.start}${app.version.code}${match.end}" />

        <property name="matchVersionName.start" value="android:versionName="" />
        <replaceregexp file="AndroidManifest.xml" match="${matchVersionName.start}[^"]*${match.end}" replace="${matchVersionName.start}${app.version.major}${app.version.minor}${match.end}" />
    </target>




到目前为止,修改文件签名打包更新版本号已经全部完成。执行ant -buildfile build.xml,在工程的bin目录下就可以看到打好的包了。

如果想对打好的包进行一些操作,利用强大的ant当然也是可以自动化的。

在build.xml中找到一个名为-post-build的target,它是留白的,共用户自行添加构建后操作。

也许你想调用一个jar包对打好的包进行处理,只需在此target中添加:

<java jar="D:/jenkins/jenkins workspace/TestFramework_semob/UpdateJar.jar" fork="true">
		<!-- to modify -->
        <arg line="'D:/jenkins/jenkins workspace/TestFramework_semob/bin/android_framework_pda.apk' ${app.version.major}${app.version.minor}"/>
		</java>


其它的处理也只需一一加在这里。

在jenkins里新建一个工程,构建前步骤里加上invoke ant, 参数-buildfile build.xml,每两个小时构建一次 H */2 * * * ,大功告成。

还没有完。如果想对一个工程打出不同AndroidManifest.xml不同签名的多个包呢? 需要在jenkins里建多个工程吗?

不需要。

只需按自己的要求修改出多份build.xml(当然只能有一个叫build.xml,其它的要换个名字) ,然后都在构建前步骤里调用它们即可。注意每个build.xml需要增加自己的invoke ant。

还有比较重要的一点:第一个invoke ant必须是clean,以保证前面的构建不会对后面的产生影响。

附build.xml文件全文 (想要的邮件索取吧)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐