2011-01-07 63 views

回答

12

我已经找到解决方案:

  1. 获取Proguard - 副本proguard.jar为已知目录(比如MyProject的/ proguard的)
  2. 准备proguard.cfg -describing什么,以及如何优化/模糊处理。在充分地阐述这个过程Proguard的的manual
  3. 准备以下ANT的build.xml(或不服这样的一个) - 伟大的感谢名单,以this guy

UPDATE完整的build.xml

<?xml version="1.0" encoding="UTF-8"?> 
<project name="MyProject" default="zipalign" basedir="."> 
    <property name="target" value="android-8"/> 
    <!--property file="default.properties" /--> 
    <property name="encoding" value="UTF-8"/> 

    <!-- dirs --> 
    <property name="sdk.dir" location="Location of Android SDK"/> 
    <property name="proguard.dir" value="proguard" /> 
    <property name="src.dir" value="src"/> 
    <property name="gen.dir" value="gen"/> 
    <property name="res.dir" value="res"/> 
    <property name="assets.dir" value="assets"/> 
    <property name="libs.dir" value="libs"/> 
    <property name="out.classes.unoptimized.dir" value="out"/> 
    <property name="out.classes.optimized.dir" value="out/optimized"/> 

    <!-- files --> 
    <property name="manifest.file" value="AndroidManifest.xml"/> 
    <property name="signed.apk" value="${ant.project.name}-signed.apk"/> 
    <property name="unsigned.apk" value="${ant.project.name}-unsigned.apk"/> 
    <property name="final.apk" value="${ant.project.name}.apk"/> 
    <property name="android.jar" value="${sdk.dir}/tools/platforms/${target}/android.jar"/> 
    <property name="unoptimized" value="unoptimized.jar" /> 
    <property name="optimized" value="optimized.jar" /> 
    <property name="proguard.config" value="${proguard.dir}/proguard.cfg"/> 

    <!-- tools --> 
    <property name="dx.jar" value="${sdk.dir}/platform-tools/lib/dx.jar"/> 
    <property name="aapt" value="${sdk.dir}/platforms/${target}/tools/aapt.exe"/> 
    <property name="zipalign" value="${sdk.dir}/tools/zipalign.exe"/> 
    <property name="jarsign" value="jarsigner.exe location is here"/> 
    <property name="keystore" value="Your key store is here"/> 
    <property name="keyalias" value="Your key alias is here"/> 


    <path id="android.antlibs"> 
     <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" /> 
     <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" /> 
     <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" /> 
     <pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" /> 
     <pathelement path="${sdk.dir}/tools/lib/jarutils.jar" /> 
    </path> 

    <taskdef name="setup" 
     classname="com.android.ant.SetupTask" 
     classpathref="android.antlibs" /> 
    <setup import="false"/> 

    <!--taskdef name="aaptexec" 
      classname="com.android.ant.AaptExecLoopTask" 
      classpathref="android.antlibs" /--> 

    <target name="clean" description="Removes output files created by other targets."> 
     <echo>Cleaning...</echo> 
     <delete dir="${out.classes.unoptimized.dir}" verbose="true" /> 
     <delete dir="${out.classes.optimized.dir}" verbose="true" /> 
    </target> 

    <target name="dirs"> 
     <echo>Creating output directories if needed...</echo> 
     <mkdir dir="${out.classes.unoptimized.dir}" /> 
     <mkdir dir="${out.classes.optimized.dir}" /> 
    </target> 

    <!-- Compiles this project's .java files into .class files. --> 
    <target name="compile" depends="dirs" 
      description="Compiles project's .java files into .class files"> 
     <echo>Compiling sources...</echo> 
     <javac encoding="${encoding}" target="1.6" debug="true" extdirs="" 
       destdir="${out.classes.unoptimized.dir}" 
       bootclasspathref="android.target.classpath" 
       includeantruntime="true"> 
      <src path="${src.dir}" /> 
      <src path="${gen.dir}" /> 
      <classpath> 
       <fileset dir="${libs.dir}" includes="*.jar" /> 
      </classpath> 
     </javac> 
    </target> 

    <target name="preobfuscate" depends="compile"> 
     <echo>Preparing to obfuscation...</echo> 
    <jar destfile="${unoptimized}" 
     basedir="${out.classes.unoptimized.dir}" 
     includes="**/**" 
     excludes="optimized/**" 
     /> 
    </target> 

    <!-- Obfuscation with ProGuard --> 
    <target name="optimize" unless="nooptimize" depends="preobfuscate"> 
     <echo>Proguard obfuscation...</echo> 
     <java jar="${proguard.dir}/proguard.jar" fork="true" failonerror="true"> 
      <jvmarg value="-Dmaximum.inlined.code.length=16" /> 
      <arg value="@${proguard.dir}/proguard.cfg" /> 
      <arg value="-injars ${unoptimized}" /> 
      <arg value="-outjars ${optimized}" /> 
      <arg value="-libraryjars ${android.jar}" /> 
     </java> 
     <unzip src="${optimized}" dest="${out.classes.optimized.dir}" /> 
     <!-- Delete optimized jar (now unzipped into bin directory) --> 
     <delete file="${optimized}"/> 
     <delete file="${unoptimized}"/> 
    </target> 

    <target name="dex" description="Converting JVM bytecodes into Dalvik bytecodes" depends="optimize"> 
     <echo>Converting bytecodes to Dalvik VM bytecodes...</echo> 
     <java jar="${dx.jar}" fork="true"> 
      <arg line="--dex --verbose --output=${out.classes.optimized.dir}/classes.dex ${out.classes.optimized.dir}"/> 
     </java> 
    </target> 

    <target name="aapt" depends="dex" description="compile resources"> 
     <echo>Packing resources...</echo> 
     <exec executable="${aapt}" logerror="true" osfamily="windows"> 
      <arg line="p 
      -f 
      -M ${manifest.file} 
      -I ${android.jar} 
      -S ${res.dir} 
      -A ${assets.dir} 
      -F ${out.classes.optimized.dir}/${unsigned.apk} 
      -m -J ${gen.dir}"/> 
     </exec> 
    </target> 

    <target name="sign" depends="aapt" description="sign apk"> 
     <input message="Please enter keystore password (store:${keystore}):" 
         addproperty="keystore.password" /> 
     <echo>Signing apk...</echo> 
     <exec executable="${jarsign}" logerror="true" osfamily="windows"> 
      <arg line="-verbose 
      -keystore ${keystore} 
      -storepass ${keystore.password} 
      -signedjar ${out.classes.optimized.dir}/${signed.apk} 
      ${out.classes.optimized.dir}/${unsigned.apk} ${keyalias}"/> 
     </exec> 
    </target> 

    <target name="zipalign" depends="sign" description="zip align"> 
     <echo>Aligning apk...</echo> 
     <exec executable="${zipalign}" logerror="true" osfamily="windows"> 
      <arg line="-f 
      -v 
      4 
      ${out.classes.optimized.dir}/${signed.apk} 
      ${final.apk}"/> 
     </exec> 
    </target> 

</project> 
  1. 在Java构建器之后和Android包构建器之前,必须将此ANT任务添加到Eclipse的构建器(属性/构建器)任务中。

  2. 按“全部构建”(这是更好地在Eclipse菜单中关闭自动生成校验)

+0

你会发布完整的build.xml吗? – eros 2011-09-16 06:35:00

9

Android构建过程首先将Java源文件(.java)编译为Java类文件(.class) ,然后将这些类文件转换为Dalvik代码(classes.dex),最后将这个Dalvik代码打包到APK文件中。

ProGuard读取和写入Java类文件,因此它必须在编译步骤和转换步骤之间插入到此管道中。它不会自己读取或写入Dalvik代码,因此无法在APK文件上运行。

Android SDK documentation on ProGuard讨论了如何在Ant build中为android-9启用混淆步骤。简而言之,您必须在文件default.properties中添加一行“proguard.config = proguard.cfg”,然后运行“ant release”。

+1

这不完全是我问的问题......我从IDE(Intellij)内​​部构建Android APK,构建之前或构建之后,我可以启动任意ANT构建任务。是否有可能以某种方式为此定义单独的ANT任务? – barmaley 2011-01-09 21:00:19

+2

由于ProGuard步骤必须在构建管道的中间执行,因此无法在IDEA构建之前或之后简单地添加Ant任务。您必须为整个构建过程创建一个Ant build.xml脚本并对其进行修改。 Android SDK中的android命令会为您创建一个Ant文件。另外,IDEA可以为你创建一个Ant文件(Build> Generate Ant build ...)。用于IDEA的IDEA Android插件似乎已经使用Android SDK创建了Ant文件。然后,您可以从IDEA运行Ant构建(右侧的菜单栏,假设Ant插件已启用)。 – 2011-01-22 11:59:51

1

proGuard混淆处理需要.class文件,因此无法在IDE构建(.java)之前或之后(.dex packed)启动Ant。

对此帖子里它解释了如何在全局Ant构建添加Proguard的一步一看:

http://www.androidengineer.com/2010/07/optimizing-obfuscating-and-shrinking.html

如果你真的想使用的理念下,你可以尝试以下。

  • IDEA构建之后,用apktool解压缩apk。
  • 转换的.DEX文件与dex2jar
  • 运行ProGuard的上一展后到的.class你

对不起,我不重视你apktool和dexjar的联系,但因为我是新手我无法发布多个超链接。

+0

我知道它,但我需要build.xml for Ant :) – barmaley 2011-01-28 09:00:44

3

注意:barmaley的回答是从2011年一年,似乎是有效的Android SDK工具版本无论是8或10

我尝试使用Android SDK工具版本18.1.1适应这一解决方案,但一直未能上的错误:
taskdef class com.android.ant.SetupTask cannot be found

即使tually,我所做的就是这样的:

rm build.xml 
android update project -p . 
  • 如果你没有在你的PATH的SDK工具,你需要使用完整路径到Android工具,例如在Windows上:C:\ Android的\ SDK \工具

这创造了一个新的build.xml这是符合当前的SDK工具,而且似乎自动很多是在barmaley的答复描述的手动工作。

之后,我是能够运行ant release,其照顾建设和混淆的结果.apk文件的开箱。

为了自动通过蚂蚁混淆,你需要:

  1. Enable Proguard obfuscator(显然)
  2. 创建ant.properties文件,并用适当的key.store PARAMS填充(见this SO reply详细内容)。