`
scliu0718
  • 浏览: 51362 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

Android之Maven集成Ant多渠道打包

 
阅读更多

在网上找了这方面的东西,貌似比较少,对maven也不是太了解,所以就想了个比较笨的办法,即用ant执行mvn命令来执行pom.xml文件,

maven只负责做打包和签名,其它的多渠道操作都是ant中处理。


ant.xml部分做循环的操作:

1. 文件替换

2. pom.xml中<appName>标签的修改

3. 执行mvn命令,打apk包及签名

Ant核心代码:

<?xml version="1.0" encoding="utf-8"?>
<project name="test" basedir="." default="run" xmlns:artifact="urn:maven-artifact-ant">
	<!-- ant build的引用 -->
	<property file="project.properties" />
	<property file="ant.properties" />
	<property file="build.properties" />

	<!-- SDK目录(获取操作系统环境变量env.ANDROID_SDK_HOME的值) -->
	<property name="sdk-folder" value="D:/Program Files/android-sdk-windows" />

	<property name="antcontrib_jar_path" value="C:/Users/Win7/Desktop/MavenAPK/ant-contrib-1.0b3.jar" />
	<property name="appName" value="AppName" />

	<property name="assetKey" value="${ant.contrib.asset.key}" />
	<property name="nowpath" value="${assetKey}" />
	<!-- 渠道名:渠道号 -->
	<property name="assetPathKey" value="${nowpath}" />

	<property name="classPath" value="a.b.ControlAnt" />
	<property name="javacPath" value="a/b/ControlAnt.java" />

	<property name="mavenPath" value="${M2_HOME}/bin" />

	<!-- 使用第三方的ant包,使ant支持for循环-->
	<taskdef resource="net/sf/antcontrib/antcontrib.properties">
		<classpath>
			<pathelement location="${antcontrib_jar_path}" />
		</classpath>
	</taskdef>

	<!-- SDK指定平台目录 -->
	<property name="sdk-platform-folder" value="${sdk-folder}/platforms/android-4" />
	<!-- SDK中tools目录 -->
	<property name="sdk-tools" value="${sdk-folder}/tools" />
	<!-- SDK指定平台中tools目录 -->
	<property name="sdk-platform-tools" value="${sdk-platform-folder}/tools" />

	<!-- 编译需要的jar; 如果项目使用到地图服务则需要maps.jar -->
	<property name="android-jar" value="${sdk-platform-folder}/android.jar" />

	<!-- 编译后的文件放置目录 -->
	<property name="outdir-target" value="target" />
	<!-- 清单文件 -->
	<property name="manifest-xml" value="AndroidManifest.xml" />
	<!-- 源文件目录 -->
	<property name="resource-dir" value="res" />
	<property name="asset-dir" value="assets" />
	<!-- java源文件目录 -->
	<property name="srcdir" value="src" />
	<property name="srcdir-ospath" value="${basedir}/${srcdir}" />
	<!-- 外部类库所在目录 -->
	<property name="external-lib" value="libs" />
	<property name="external-lib-ospath" value="${basedir}/${external-lib}" />

	<!-- 生成class目录 -->
	<property name="outdir-classes-ospath" value="${basedir}/${outdir-target}" />

	<!-- 替换文件key : value -->
	<property name="assetchannelname" value="" />
	<property name="assetchannelvalue" value="" />

	<!-- 循环修改路徑名 -->
	<target name="run">
		<foreach target="update_replace_path" list="${assetKey}" param="assetchannel" delimiter=",">
		</foreach>
	</target>


	<!-- 修改nowpath,并根据nowpath替换文件、打包 -->
	<target name="update_replace_path">
		<echo>
			  master.xml I passed PARAMETER passed-info with value ---------${assetchannel}
		</echo>
		<replaceregexp flags="nowpath" byline="false" encoding="UTF-8">
			<regexp pattern='nowpath=(.*)' />
			<substitution expression='nowpath=${assetchannel}' />
			<fileset dir="${basedir}" includes="ant.properties" />
		</replaceregexp>

		<mkdir dir="${outdir-classes-ospath}/classes" />

		<!-- 此java类就做了一件事,通过循环的值assetchannel(path名称)读取到对应的值赋给nowpath -->
		<javac srcdir="src" includes="${javacPath}" destdir="${outdir-classes-ospath}" classpath="${outdir-classes-ospath}">
		</javac>

		<java classname="${classPath}">
			<arg value="${assetchannel}" />
			<classpath>
				<pathelement path="./bin/classes" />
			</classpath>
		</java>

		<antcall target="maven-apk">
		</antcall>
	</target>


	<!--根据path值循环替换文件 -->
	<target name="deploy">
		<echo level="info">Modify the asset files...</echo>
		<foreach target="modify_content_by_path" list="${assetPathKey}" param="assetpathchannel" delimiter=",">
		</foreach>

		<!-- 清理 -->
		<delete includeemptydirs="true" verbose="true">
			<fileset dir="${outdir-classes-ospath}" excludes="*.apk,classes">
			</fileset>
		</delete>
	</target>

	<!-- 替换需修改的文件并修改AppName -->
	<target name="modify_content_by_path">
		<!-- 获取渠道名字 -->
		<propertyregex override="true" property="assetchannelname" input="${assetpathchannel}" regexp="(.*)::" select="\1" />
		<!-- 获取渠道号码 -->
		<propertyregex override="true" property="assetchannelvalue" input="${assetpathchannel}" regexp="::(.*)" select="\1" />

		<echo level="info">Replace ----- ${assetchannelname}......${assetchannelvalue}.........</echo>

		<if>
			<equals arg1="${appName}" arg2="${assetchannelname}" />
			<then>
				<!-- 修改pom文件的appName标签,确定打包后的apk名称 -->
				<replaceregexp flags="g" byline="false" encoding="UTF-8">
					<regexp pattern='\x3CappName\x3E(.*)\x3C/appName\x3E' />
					<substitution expression="<appName>${assetchannelvalue}</appName>" />
					<fileset dir="${basedir}" includes="pom.xml" />
				</replaceregexp>
			</then>
			<else>
				<!-- 开始替换文件 -->
				<available property="file.exist" file="${assetchannelname}" />
				<if>
					<isset property="file.exist" />
					<then>
						<filter filtersfile="${assetchannelname}" />
						<copy file="${assetchannelname}" overwrite="true" preservelastmodified="true" todir="./${assetchannelvalue}" verbose="true">
						</copy>
					</then>
					<else>
						<echo level="error">Error: "${assetchannelname}" 文件不存在</echo>
					</else>
				</if>
			</else>
		</if>
	</target>

	<target name="maven-apk" depends="deploy">
		<!-- 通过 执行maven命令来打apk包,前提是先配置maven到环境变量  -->
		<exec command="mvn.bat">
			<arg value="-f" />
			<arg value="${basedir}/pom.xml" />
			<arg value="compile" />
			<arg value="package" />
		</exec>

		<echo level="verbose">--------BUILD SUCCESSFULL---------</echo>
	</target>

</project>


配置信息:

ant.properies: ----> 属性配置信息,由于在maven中的setting.xml配置了keystore信息,所以此配置可略掉

build.properies: ----> 需替换的文件配置信息,可把ant.properties整合

ant.properies:

key.store=LS.keystore
key.alias=LS
key.store.password=xxxxxxx
key.alias.password=xxxxxxx
jdk.version=1.6


build.properties:

#Update nowpath value
#Mon Apr 08 13:29:02 CST 2013
ant.contrib.asset.key=path,path1,path2
path2=E\:/a.png\:\:res/drawable-hdpi,E\:/b.png\:\:res/drawable-hdpi,E\:/c.png\:\:res/drawable-hdpi,E\:/ic_launcher.png\:\:res/drawable-hdpi,AppName\:\:MavenAnt2
path=E\:/a.png\:\:res/drawable-hdpi,E\:/b.png\:\:res/drawable-hdpi,E\:/c.png\:\:res/drawable-hdpi,E\:/ic_launcher.png\:\:res/drawable-hdpi,AppName\:\:MavenAnt
path1=E\:/a.png\:\:res/drawable-hdpi,E\:/b.png\:\:res/drawable-hdpi,E\:/c.png\:\:res/drawable-hdpi,E\:/ic_launcher.png\:\:res/drawable-hdpi,AppName\:\:MavenAnt1
nowpath=E\:/a.png\:\:res/drawable-hdpi,E\:/b.png\:\:res/drawable-hdpi,E\:/c.png\:\:res/drawable-hdpi,E\:/ic_launcher.png\:\:res/drawable-hdpi,AppName\:\:MavenAnt2



AntControl.java根据path/path1/path2修改nowpath的值,如果没有此需求可以省略这一步。(在ant中循环ant.contrib.asset.key的值path为${assetchanel},

以${assetchanel}为key取出"E:\......"的时候取的值总为key的值,path本来就是value,应该有办法的,有人知道的话告诉我一下,所以又定义 了一个nowpath

而且还是在java中去修改,这样比较麻烦)。

AntControl.java

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
//This class is a util class , in order to pack apk file. 
public class ControlAnt {

	public static void main(String[] args) {
		try {
			InputStream in = new FileInputStream("build.properties");
			Properties properties = new Properties();

			properties.load(in);

			//路径名
			String str = (String) properties.get(args[0]);
			String property = properties.getProperty(str, str);
			//通过路径名拿到路径value,然后赋给nowpath
			properties.setProperty("nowpath", property);

			FileOutputStream fos = new FileOutputStream("build.properties");
			properties.store(fos, "Update" + " nowpath " + "value");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}


以下是maven模块的配置:

<?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>

	<artifactId>MavenAnt</artifactId>
	<groupId>a.b</groupId>
	<version>2.1.2</version>
	<packaging>apk</packaging>
	<name>MavenAnt</name>

	<properties>
	    <!-- ant中修改此标签,决定打包后apk名称,达到多渠道打包目的 -->
		<appName>MavenAnt</appName>
	</properties>

	<dependencies>
		<dependency>
			<groupId>com.google.android</groupId>
			<artifactId>android</artifactId>
			<version>2.1.2</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>

	<build>
		<finalName>${appName}</finalName>

		<plugins>
			<plugin>
				<groupId>com.jayway.maven.plugins.android.generation2</groupId>
				<artifactId>android-maven-plugin</artifactId>
				<version>3.0.0-alpha-14</version>
				<configuration>
					<encoding>UTF-8</encoding>
					<androidManifestFile>${project.basedir}/AndroidManifest.xml</androidManifestFile>
					<assetsDirectory>${project.basedir}/assets</assetsDirectory>
					<resourceDirectory>${project.basedir}/res</resourceDirectory>
					<nativeLibrariesDirectory>${project.basedir}/src/main/native</nativeLibrariesDirectory>
					<sdk>
						<path>${env.ANDROID_HOME}</path>
						<platform>8</platform>
					</sdk>
					<deleteConflictingFiles>true</deleteConflictingFiles>
					<undeployBeforeDeploy>true</undeployBeforeDeploy>
				</configuration>
				<extensions>true</extensions>
			</plugin>

			<!-- 精减打包 -->
			<!--plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> 
				<version>1.2.1</version> <executions> <execution> <id>zipalign</id> <goals> 
				<goal>exec</goal> </goals> <phase>install</phase> <configuration> <executable>${ANDROID_HOME}/tools/zipalign</executable> 
				<arguments> <argument>-f</argument> <argument>4</argument> <argument>target/${appName}.apk</argument> 
				<argument>target/${appName}-sign.apk</argument> </arguments> <tasks> </tasks> 
				</configuration> </execution> <execution> </execution> </executions> </plugin -->

			<!-- 签名 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jarsigner-plugin</artifactId>
				<version>1.2</version>
				<executions>
					<execution>
						<id>signing</id>
						<goals>
							<goal>sign</goal>
						</goals>
						<phase>package</phase>
						<inherited>true</inherited>
						<configuration>
							<archiveDirectory></archiveDirectory>
							<encoding>UTF-8</encoding>
							<includes>
								<argument>target/${appName}.apk</argument>
							</includes>
							<removeExistingSignatures>true</removeExistingSignatures>
							<keystore>${keyFilePath}</keystore>
							<storepass>${storePassword}</storepass>
							<keypass>${keyPassword}</keypass>
							<alias>${keyAlias}</alias>
							<deleteConflictingFiles>true</deleteConflictingFiles>
						</configuration>
					</execution>
				</executions>
			</plugin>

		</plugins>
	</build>
</project>

在setting.xml中的profiles中添加:

<!-- 打包新增 -->
	<profile>
		<id>sign</id>
		<activation>
			<activeByDefault>true</activeByDefault>
		</activation>
		<properties>
			<keyFilePath>C:\Users\Win7\Desktop\Task\LS.keystore</keyFilePath>
			<storePassword>xxxxxxx</storePassword>
			<keyPassword>xxxxxxx</keyPassword>
			<keyAlias>LS</keyAlias>
		</properties>
	</profile>



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics