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}" failonerror="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}" failonerror="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" failonerror="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" failonerror="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" failonerror="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" failonerror="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" failonerror="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}" failonerror="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}" failonerror="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}" failonerror="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}" failonerror="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(); } }