1.先来一个基础的配置文件(build.properties)
##最后生成目录
#relase.abs.dir=C:\\Users\\Administrator\\Desktop
#
##工程绝对路径
#storeapp.abs=F:\\ZhangLeRepository\\trunk\\Andorid\\StoreApp
#photoview.abs=F:\\ZhangLeRepository\\trunk\\Andorid\\PhotoView
#andbase.abs=F:\\ZhangLeRepository\\trunk\\Andorid\\AndBase
#xutils.abs=F:\\ZhangLeRepository\\trunk\\Andorid\\xutils
#
##SDK相关工具变量
#sdk.home=F:\\adt\\sdk
#sdk.platform=android-19
#jdk.home=F:\\java
#
#
##签名配置
#keystore.path=???
#keystore.storepass=???
#keystore.keypass=???
#keystore.alias=???
3.上bulid.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Build an Android project. -->
<project name="StoreApp" basedir="." default="release" >
<!-- 通用属性 -->
<property file="build.properties" />
<!-- 主工程绝对路径 -->
<property name="storeapp.abs.src" value="${storeapp.abs}/src" />
<property name="storeapp.abs.bin" value="${storeapp.abs}/bin" />
<property name="storeapp.abs.gen" value="${storeapp.abs}/gen" />
<property name="storeapp.abs.res" value="${storeapp.abs}/res" />
<property name="storeapp.abs.lib" location="${storeapp.abs}\libs" />
<property name="storeapp.abs.assets" value="${storeapp.abs}/assets" />
<property name="androidManifest.abs" value="${storeapp.abs}/AndroidManifest.xml" />
<property name="storeapp.abs.dex" value="${storeapp.abs}/bin/classes.dex" />
<property name="storeapp.abs.resources" value="${storeapp.abs}/bin/resources.ap_" />
<property name="storeapp.abs.unsigned" value="${storeapp.abs.bin}/${ant.project.name}-unsigned.apk" />
<property name="storeapp.abs.signed" value="${storeapp.abs.bin}/${ant.project.name}.apk" />
<property name="storeapp.package.name" value="com.zhangle.storeapp" />
<!-- lib工程相关配置 andbase-->
<property name="andbase.abs.res" location="${andbase.abs}\res" />
<property name="andbase.abs.src" location="${andbase.abs}\src" />
<property name="andbase.abs.lib" location="${andbase.abs}\libs" />
<property name="andbase.package.name" value="com.ab" />
<!-- lib工程相关配置 photoview-->
<property name="photoview.abs.res" location="${photoview.abs}\res" />
<property name="photoview.abs.src" location="${photoview.abs}\src" />
<property name="photoview.abs.lib" location="${photoview.abs}\libs" />
<property name="photoview.package.name" value="uk.co.senab.photoview" />
<!-- lib工程相关配置 xutils-->
<property name="xutils.abs.res" location="${xutils.abs}\res" />
<property name="xutils.abs.src" location="${xutils.abs}\src" />
<property name="xutils.abs.lib" location="${xutils.abs}\libs" />
<property name="xutils.package.name" value="com.lidroid.xutils" />
<!--打包工具的绝对路径. -->
<property name="android.framework" value="${sdk.home}/platforms/${sdk.platform}/framework.aidl" />
<property name="android.core" value="${sdk.home}/platforms/${sdk.platform}/android.jar" />
<property name="android.proguard" value="${sdk.home}/tools/proguard/lib/proguard.jar" />
<property name="android.support.lib" value="${sdk.home}/tools/support" />
<property name="jarsigner" value="${jdk.home}/bin/jarsigner.exe" />
<property name="zipalign" value="${sdk.home}/tools/zipalign.exe" />
<property name="dx" value="${sdk.home}/build-tools/android-4.4/dx.bat" />
<property name="apk-builder" value="${sdk.home}/tools/apkbuilder.bat" />
<property name="aapt" value="${sdk.home}/build-tools/android-4.4/aapt.exe" />
<property name="aidl" value="${sdk.home}/build-tools/android-4.4/aidl.exe" />
<property name="adb" value="${sdk.home}/platform-tools/adb.exe" />
<!-- 1.Cleaning the project -->
<target name="1clean" >
<echo>Cleaning the project...</echo>
<delete
includeemptydirs="true"
verbose="true" >
<fileset
dir="${storeapp.abs.bin}"
includes="**/*" >
</fileset>
</delete>
<delete
includeemptydirs="true"
verbose="true" >
<fileset
dir="${storeapp.abs.gen}"
includes="**/*" >
</fileset>
</delete>
</target>
<!-- 2 Generate R.java -->
<target name="2generate" depends="1clean" >
<echo>Generating R.java / Manifest.java from the resources... </echo>
<exec executable="${aapt}" failοnerrοr="true" >
<arg value="package" />
<arg value="-f" />
<arg value="-m" />
<arg value="--auto-add-overlay" />
<arg value="-J" />
<arg value="${storeapp.abs.gen}" />
<arg value="-M" />
<arg value="${androidManifest.abs}" />
<arg value="-S" />
<arg value="${storeapp.abs.res}" />
<arg value="-S" />
<arg value="${andbase.abs.res}" /> <!-- Library Project的路径-->
<arg value="--extra-packages" />
<arg value="${andbase.package.name}" /><!-- Library Project的包名 -->
<arg value="-S" />
<arg value="${photoview.abs.res}" /> <!-- Library Project的路径-->
<arg value="--extra-packages" />
<arg value="${photoview.package.name}" /><!-- Library Project的包名 -->
<arg value="-S" />
<arg value="${xutils.abs.res}" /> <!-- Library Project的路径-->
<arg value="--extra-packages" />
<arg value="${xutils.package.name}" /><!-- Library Project的包名 -->
<arg value="-A" />
<arg value="${storeapp.abs.assets}" />
<!-- Library Project的包名 -->
<arg value="-I" />
<arg value="${android.core}" />
</exec>
</target>
<!-- 3Convert and compile AIDL files. -->
<target name="3aidl" depends="2generate" >
<echo>Compiling aidl files into Java classes...</echo>
<apply executable="${aidl}" failοnerrοr="true" >
<arg value="-p${android.framework}" />
<arg value="-I${storeapp.abs.src}" />
<arg value="-o${storeapp.abs.gen}" />
<fileset dir="${storeapp.abs.src}" >
<include name="**/*.aidl" >
</include>
</fileset>
</apply>
</target>
<!-- 额外加入生成BuildConfig的过程 -->
<!-- 生成BuildConfig.java文件 -->
<target name="gen-storeapp-BuildConfig">
<echo>Generating BuildConfig.java...</echo>
<java jar="${basedir}/genBulidConfig.jar" fork="true" failοnerrοr="true">
<jvmarg value="-Dmaximum.inlined.code.length=32" />
<arg value="abdir" />
<arg value="${storeapp.abs.gen}" />
<arg value="pakage" />
<arg value="${storeapp.package.name}" />
<arg value="debug" />
<arg value="false" />
</java>
</target>
<target name="gen-andbase-BuildConfig">
<echo>Generating BuildConfig.java...</echo>
<java jar="${basedir}/genBulidConfig.jar" fork="true" failοnerrοr="true">
<jvmarg value="-Dmaximum.inlined.code.length=32" />
<arg value="abdir" />
<arg value="${storeapp.abs.gen}" />
<arg value="pakage" />
<arg value="${andbase.package.name}" />
<arg value="debug" />
<arg value="false" />
</java>
</target>
<target name="gen-photoview-BuildConfig" >
<echo>Generating BuildConfig.java...</echo>
<java jar="${basedir}/genBulidConfig.jar" fork="true" failοnerrοr="true">
<jvmarg value="-Dmaximum.inlined.code.length=32" />
<arg value="abdir" />
<arg value="${storeapp.abs.gen}" />
<arg value="pakage" />
<arg value="${photoview.package.name}" />
<arg value="debug" />
<arg value="false" />
</java>
</target>
<target name="gen-xutils-BuildConfig" >
<echo>Generating BuildConfig.java...</echo>
<java jar="${basedir}/genBulidConfig.jar" fork="true" failοnerrοr="true">
<jvmarg value="-Dmaximum.inlined.code.length=32" />
<arg value="abdir" />
<arg value="${storeapp.abs.gen}" />
<arg value="pakage" />
<arg value="${xutils.package.name}" />
<arg value="debug" />
<arg value="false" />
</java>
</target>
<!-- 4Compile srcdir="${framework_src.abs}:${src.abs}:${gen.abs}" 表示编译的源文件目录有三个 -->
<target name="4compile" depends="1clean,2generate,3aidl,gen-storeapp-BuildConfig,gen-xutils-BuildConfig,gen-photoview-BuildConfig,gen-andbase-BuildConfig" >
<javac bootclasspath="${android.core}"
debug="off"
destdir="${storeapp.abs.bin}"
encoding="UTF-8"
extdirs=""
includeantruntime="false"
srcdir="${storeapp.abs.src}:${storeapp.abs.gen}:${andbase.abs.src}:${photoview.abs.src}:${xutils.abs.src}"
target="1.7" >
<classpath>
<fileset dir="${storeapp.abs.lib}" includes="*.jar" />
<fileset dir="${andbase.abs.lib}" includes="*.jar" />
<fileset dir="${photoview.abs.lib}" includes="*.jar" />
<fileset dir="${xutils.abs.lib}" includes="*.jar" />
</classpath>
</javac>
</target>
<!-- 混淆代码 -->
<target name="proguard" depends="4compile">
<echo>proguard...</echo>
<jar basedir="${storeapp.abs.bin}" destfile="temp.jar" />
<java jar="${android.proguard}" fork="true" failοnerrοr="true">
<jvmarg value="-Dmaximum.inlined.code.length=32" />
<arg value="-injars temp.jar" />
<arg value="-outjars optimized.jar" />
<arg value="-dontwarn" />
<arg value="-dontpreverify" />
<arg value="-dontoptimize" />
<arg value="-dontusemixedcaseclassnames" />
<arg value="-repackageclasses ''" />
<arg value="-allowaccessmodification" />
<arg value="-optimizationpasses 7" />
<arg value="-verbose" />
<arg value="-dontnote " />
<arg value="-dontskipnonpubliclibraryclasses" />
<arg value="-dontskipnonpubliclibraryclassmembers" />
<!-- jar包不混淆 -->
<arg value="-libraryjars ${android.core}" />
<arg value="-libraryjars ${storeapp.abs.lib}/android-support-v4.jar" />
<arg value="-libraryjars ${storeapp.abs.lib}/fastjson-1.1.39.jar" />
<arg value="-libraryjars ${storeapp.abs.lib}/zbar.jar" />
<!-- 要保留自己的主ACTIVITY类 -->
<arg value="-keepattributes *Annotation* " />
<arg value="-keep class * extends android.app.Activity" />
<arg value="-keep class * extends android.app.Application" />
<arg value="-keep class * extends android.app.Service" />
<arg value="-keep class * extends android.content.BroadcastReceiver" />
<arg value="-keep class * extends android.content.ContentProvider" />
<arg value="-keep class * extends android.view.View" />
<arg value="-keepclasseswithmembernames class * {native <methods>;} " />
<arg value="-keepclassmembers public class * extends android.view.View { void set*(***); *** get*();}" />
<arg value="-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String);}" />
<arg value="-keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *;}" />
<arg value="-keepclassmembers class **.R$* { public static <fields>;}" />
<arg value="-dontwarn android.support.** " />
<arg value="-dontwarn com.alibaba.fastjson.** " />
<!-- fastjson -->
<arg value="-keep class com.alibaba.fastjson.** { *; } " />
<arg value="-keepclassmembers class * { public <methods>;} " />
<arg value="-keepattributes Signature " />
<arg value="-keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve(); public <fields>;}" />
<!--其他-->
<arg value="-keep class * extends java.lang.annotation.Annotation { *; }" />
<arg value="-keep class * extends com.zhangle.storeapp.db.entity.** " />
<arg value="-keep class com.zhangle.storeapp.ctview.pickerview.AddressSelectWindow " />
<arg value="-keep class com.zhangle.storeapp.BuildConfig " />
<!-- 保留下拉刷新库 -->
<arg value="-keep class com.handmark.pulltorefresh.library.** {*;} " />
<arg value="-keep class com.ab.** {*;} " />
<arg value="-keep class com.lidroid.xutils.** {*;} " />
<arg value="-keep class uk.co.senab.photoview.** {*;} " />
<arg value="-keep class com.zhangle.storeapp.utils.ReflectResouceID " />
</java>
<delete file="temp.jar" />
<delete dir="${storeapp.abs.bin}" />
<mkdir dir="${storeapp.abs.bin}" />
<unzip src="optimized.jar" dest="${storeapp.abs.bin}" />
<delete file="optimized.jar" />
</target>
<!-- 5Convert and compress .class files to .dex file. -->
<target name="5dex" depends="proguard" >
<echo>Converting compiled files and external libraries into dex format file...</echo>
<apply executable="${dx}" failοnerrοr="true" parallel="true" >
<arg value="--dex" />
<arg value="--output=${storeapp.abs.dex}" />
<arg path="${storeapp.abs.bin}" />
<fileset
dir="${storeapp.abs.lib}"
includes="*.jar" >
</fileset>
<fileset
dir="${andbase.abs.lib}"
includes="*.jar" >
<exclude name="*android-support-v4.jar"/>
</fileset>
<fileset
dir="${photoview.abs.lib}"
includes="*.jar" >
<exclude name="*android-support-v4.jar"/>
</fileset>
<fileset
dir="${xutils.abs.lib}"
includes="*.jar" >
<exclude name="*android-support-v4.jar"/>
</fileset>
</apply>
</target>
<!-- 6Package the resources. -->
<target name="6package" depends="5dex">
<echo>Packaging resources and assets...</echo>
<exec executable="${aapt}" failοnerrοr="true" >
<arg value="package" />
<arg value="-f" />
<arg value="-m" />
<arg value="--auto-add-overlay" />
<arg value="-M" />
<arg value="${androidManifest.abs}" />
<arg value="-S" />
<arg value="${storeapp.abs.res}" />
<arg value="-S" />
<arg value="${andbase.abs.res}" />
<arg value="-S" />
<arg value="${photoview.abs.res}" />
<arg value="-S" />
<arg value="${xutils.abs.res}" />
<arg value="-A" />
<arg value="${storeapp.abs.assets}" />
<arg value="-I" />
<arg value="${android.core}" />
<arg value="-F" />
<arg value="${storeapp.abs.resources}" />
</exec>
</target>
<!-- 7Package an unsigned APK file. -->
<target name="7genUnsignedApk" depends="5dex, 6package" >
<echo>Packaging an unsigned APK file...</echo>
<exec executable="${apk-builder}" failοnerrοr="true" >
<arg value="${storeapp.abs.unsigned}" />
<arg value="-u" />
<arg value="-z" />
<arg value="${storeapp.abs.resources}" />
<arg value="-f" />
<arg value="${storeapp.abs.dex}" />
<arg value="-rf" />
<arg value="${storeapp.abs.src}" />
<!-- 加jar库到应用包中 -->
<!-- arg value="-rj" /-->
<!-- arg value="${libproject.abs.lib}" /-->
<!-- 加动态连接库到应用包中 -->
<arg value="-nf" />
<arg value="${storeapp.abs.lib}" />
</exec>
</target>
<!-- 对apk进行签证 -->
<target name="9genSignedApk" depends="7genUnsignedApk">
<echo>Packaging signed apk for release...</echo>
<exec executable="${jarsigner}" failοnerrοr="true" >
<arg value="-verbose" />
<arg value="-keystore" />
<arg value="${keystore.path}" />
<arg value="-storepass" />
<arg value="${keystore.storepass}" />
<arg value="-keypass" />
<arg value="${keystore.keypass}" />
<arg value="-signedjar" />
<arg value="${storeapp.abs.signed}" />
<arg value="${storeapp.abs.unsigned}" />
<!-- 不要忘了证书的别名 -->
<arg value="${keystore.alias}"/>
</exec>
</target>
</project>
3.其中有个buildconfig的工具,这里共享源码,到处为可运行的jar即可
/**
* 2014-6-11 上午11:07:22
* Created By niexiaoqiang
*/
package com.xiaoqiang.genbuildconfig;
import java.io.File;
import java.io.FileWriter;
import java.util.HashMap;
/**
* 生成BuildConfig文件
* @author niexiaoqiang
*/
public class GenBuildConfig {
public static final String ABDIR = "abdir";
public static final String PACKAGE = "pakage";
public static final String DEBUG = "debug";
public static final String FILENAME = "BuildConfig.java";
public static void main(String[] args) {
int paramsLength = args.length;
if (paramsLength % 2 == 0) {
HashMap<String, Object> params = new HashMap<String, Object>();
for (int i = 0; i < paramsLength; i = i + 2) {
params.put(args[i], args[i + 1]);
}
String content = getBuildConfigContent(params);
//创建文件夹
File dir = new File(params.get(ABDIR).toString());
if (!dir.exists()) {
dir.mkdirs();
}
createFile(content, dir, params.get(PACKAGE).toString());
}
}
/**
* 创建文件
* @param content
* @param dir
* @param packageStr
*/
public static void createFile(String content, File dir, String packageStr) {
File javaFileDir = new File(dir, packageStr.replace(".", "\\"));
if (!javaFileDir.exists()) {
javaFileDir.mkdirs();
}
File javaFile = new File(javaFileDir, FILENAME);
javaFile.setWritable(true);
try {
FileWriter writer = new FileWriter(javaFile, false);
writer.write(content);
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 生成文件内容
* @param params
* @return
*/
public static String getBuildConfigContent(HashMap<String, Object> params) {
StringBuilder sb = new StringBuilder();
sb.append("/**\r\n");
sb.append(" * Create By com.xiaoqiang.genbuildconfig\r\n");
sb.append(" */\r\n");
sb.append("\r\n");
sb.append("package " + params.get(PACKAGE) + ";\r\n");
sb.append("\r\n");
sb.append("public final class BuildConfig {\r\n");
sb.append(" public final static boolean DEBUG = " + params.get(DEBUG) + ";\r\n");
sb.append("}");
return sb.toString();
}
}