使用Jenkins进行android项目的自动构建(2)
Maven and POM
1. 什么是Maven?
官方的解释是: http://maven.apache.org/guides/getting-started/index.html#What_is_Maven
2. 什么是POM
官方的解释是: http://maven.apache.org/pom.html#What_is_the_POM
3. POM的具体例子
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example.demo</groupId> <artifactId>maven-demo</artifactId> <version>1.0.0</version> <packaging>apk</packaging> <dependencies> <!-- 加入android依赖,scope=provided --> <dependency> <groupId>com.google.android</groupId> <artifactId>android</artifactId> <version>4.1.1.4</version> <scope>provided</scope> </dependency> <!-- 加入android项目依赖,type=apklib --> <!-- 如果是android library形式的依赖,需使用这种,使用前需要将项目打包成apklib并上传到仓库 --> <!-- 如果使用maven打包library依赖,pom.xml需改用 <packaging>apklib</packaging> ,并用install命令上传 --> <dependency> <groupId>com.example.demo</groupId> <artifactId>android-framework</artifactId> <version>1.0.0</version> <type>apklib</type> </dependency> <!-- 加入facebook依赖,type=aar --> <dependency> <groupId>fr.avianey</groupId> <artifactId>facebook-android-api</artifactId> <version>3.8.0</version> <type>aar</type> </dependency> <!-- 加入android support依赖 --> <dependency> <groupId>com.google.android</groupId> <artifactId>support-v4</artifactId> <version>r7</version> </dependency> <!-- 加入junit依赖,scope=test --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.build.timestamp.format>yyyy-MM-dd-HH-mm-ss</maven.build.timestamp.format><!-- 增加一个时间戳的属性,生成的apk名可以加入该属性 --> </properties> <profiles> <profile> <id>dev</id> <properties> <package.type>dev</package.type><!-- 增加一个包类型的属性,mvn命令以参数-P传入,生成的apk名可以加入该属性 --> </properties> <build> <!-- 打包后替换apk中的指定文件 --> <!-- <resources> <resource> <directory>res\values\dev</directory> <targetPath>config</targetPath> <includes> <include>strings.*</include> </includes> </resource> <resource> <directory>res\layout</directory> <filtering>true</filtering> <includes> <include>*.*</include> </includes> </resource> </resources> --> </build> </profile> <profile> <id>prod</id> <properties> <package.type>prod</package.type><!-- 增加一个包类型的属性,mvn命令以参数-P传入,生成的apk名可以加入该属性 --> </properties> <build><!-- <resources> <resource> <directory>res\values\prod</directory> <targetPath>config</targetPath> <includes> <include>*.*</include> </includes> </resource> </resources>--> </build> </profile> </profiles> <build> <sourceDirectory>src</sourceDirectory><!-- 源代码目录 --> <testSourceDirectory>test</testSourceDirectory><!-- 测试代码目录 --> <finalName>${project.artifactId}_${project.version}_${package.type}_${maven.build.timestamp}</finalName><!-- 生成的apk文件名 --> <plugins> <!-- android-maven-plugin,打包apk --> <plugin> <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>android-maven-plugin</artifactId> <version>3.8.2</version> <configuration> <sdk> <platform>19</platform> <!-- <path>D:\adt-bundle\sdk</path> --> </sdk> <!-- "false"执行代码混淆 --> <proguard> <skip>false</skip><!-- <config>proguard.cfg</config> <jvmArguments> <jvmArgument>-Xms256m</jvmArgument> <jvmArgument>-Xmx512m</jvmArgument> </jvmArguments>--> </proguard> <deleteConflictingFiles>true</deleteConflictingFiles> <undeployBeforeDeploy>true</undeployBeforeDeploy> <sign> <debug>false</debug><!-- 生成未签名的apk --> </sign> </configuration> <extensions>true</extensions> <inherited>true</inherited> </plugin> <!-- maven-jarsigner-plugin,用于创建签名 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jarsigner-plugin</artifactId> <version>1.3.2</version> <executions> <execution> <id>signing</id> <goals> <goal>sign</goal> </goals> <phase>package</phase> <inherited>true</inherited> <configuration> <removeExistingSignatures>true</removeExistingSignatures> <archiveDirectory></archiveDirectory> <!-- SF 和 RSA的文件名 --> <sigfile>CERT</sigfile> <!-- 用于签名的apk(貌似这一项不起作用) --> <includes> <include>${project.artifactId}_${project.version}_${package.type}_${maven.build.timestamp}.apk</include> </includes> <keystore>D:\keys\key.store</keystore><!-- keystore位置 --> <storepass>123456</storepass><!-- store密码 --> <keypass>123456</keypass><!-- key密码--> <alias>maven_demo</alias><!-- alias --> <verbose>false</verbose><!-- 是否输出过程讯息 --> <!-- 指定加密算法 --> <arguments> <argument>-sigalg</argument><argument>MD5withRSA</argument> <argument>-digestalg</argument><argument>SHA1</argument> </arguments> </configuration> </execution> </executions> </plugin> <plugin> <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>maven-android-plugin</artifactId> <version>2.8.4</version> <inherited>true</inherited> <configuration> <sign> <debug>false</debug> </sign> <!-- zipalign对齐优化 --> <zipalign> <verbose>false</verbose> <inputApk>target\${project.artifactId}_${project.version}_${package.type}_${maven.build.timestamp}.apk</inputApk> <outputApk>target\${project.artifactId}_${project.version}_${package.type}_${maven.build.timestamp}-aligned.apk</outputApk> </zipalign> </configuration> <executions> <execution> <id>alignApk</id> <phase>package</phase> <goals> <goal>zipalign</goal> </goals> </execution> </executions> </plugin> <!-- jacoco plugin检查测试代码覆盖率 --> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.7.1.201405082137</version> <executions> <!-- prepare agent for measuring integration tests --> <execution> <id>jacoco-initialize</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>jacoco-site</id> <phase>post-integration-test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <!-- 生成测试代码覆盖率报告 --> <reporting> <plugins> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.7.1.201405082137</version> <reportSets> <reportSet> <reports> <report>report</report> </reports> </reportSet> </reportSets> </plugin> </plugins> </reporting> </project>
例子中各个plugin的版本互相有依赖关系的,如果换了其他版本,有可能导致失败。有时在运行测试的过程会提示java.lang.RuntimeException: Stub! at junit.framework.Assert.assertEquals(Assert.java:30),可以尝试调整dependencies中的依赖顺序来解决问题。
最后打包出来的apk,可以用aapt dump badging APK文件名来查看包信息,解压出CERT.RSA,用keytool -printcert -file CERT.RSA 命令来查看签名的MD5、SHA1、SHA256值及签名算法。