Сборка ANT для обфускации Android Proguard

Может ли кто-нибудь поделиться с образцом / простой задачей обфускации ANT для Android? При условии, что у меня есть полный APK, и мне нужно просто пройти * class hru Proguard, а затем подготовить * .dex для сборки APK.


person Barmaley    schedule 07.01.2011    source источник


Ответы (4)


Я нашел решение:

  1. Получите Proguard - скопируйте proguard.jar в известный каталог (скажем, MyProject / proguard)
  2. Подготовьте proguard.cfg - описание того, что и как оптимизировать / запутывать. Этот процесс подробно описан в руководстве Proguard.
  3. Подготовьте следующий файл build.xml ANT (или что-то вроде этого) - большое спасибо этому парню < / а>

ОБНОВЛЕНИЕ, завершение 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. Эта задача ANT должна быть добавлена ​​в задачи построителей Eclipse (Свойства / Строители) после построителя Java и перед построителем пакетов Android.

  2. Нажмите "Build All" (лучше отключить автоматическую проверку сборки в меню Eclipse)

person Barmaley    schedule 14.02.2011
comment
вы бы опубликовали полный build.xml? - person eros; 16.09.2011
comment
Почему вы добавили, что лучше отключить автоматическую проверку сборки в меню Eclipse? Это значительно медленнее, чем стандартные компоновщики Eclipse для Java / Android? Если да, то это только из-за шага Proguard или процесс сборки ant плохо обнаруживает зависимости? - person Jeff Axelrod; 30.09.2011
comment
@eros Я опубликовал полный build.xml - person Barmaley; 01.11.2011

Процесс сборки Android сначала компилирует исходные файлы Java (.java) в файлы классов Java (.class), затем конвертирует эти файлы классов в код Dalvik (classes.dex) и, наконец, упаковывает этот код Dalvik в файл APK.

ProGuard читает и записывает файлы классов Java, поэтому он должен быть вставлен в этот конвейер между этапом компиляции и этапом преобразования. Он не читает и не записывает код Dalvik, поэтому не может работать с файлом APK.

В документации Android SDK на ProGuard обсуждается, как включить этап обфускации в сборке Ant для android- 9. Короче говоря, вам нужно добавить строку «proguard.config = proguard.cfg» в файл default.properties, а затем запустить «ant release».

person Eric Lafortune    schedule 07.01.2011
comment
Это не совсем то, о чем я спрашивал ... Я создаю Android APK из IDE (Intellij), и перед сборкой или после сборки я могу запустить произвольную задачу сборки ANT. Можно ли как-то выделить для этого отдельную задачу ANT? - person Barmaley; 10.01.2011
comment
Поскольку шаг ProGuard должен выполняться в середине конвейера сборки, невозможно просто добавить задачу Ant до или после сборки IDEA. Вам нужно будет создать сценарий Ant build.xml для всего процесса сборки и изменить его. Команда android из Android SDK создает для вас файл Ant. В качестве альтернативы, IDEA может создать для вас файл Ant (Сборка ›Создать сборку Ant ...). Плагин IDEA Android для IDEA, похоже, уже создает файл Ant с помощью Android SDK. Затем вы можете запустить сборку Ant из IDEA (строка меню справа, если плагин Ant включен). - person Eric Lafortune; 22.01.2011

Внимание: ответ barmaley относится к 2011 году и, похоже, действителен для Android SDK Tools версии 8 или 10.

Я попытался адаптировать это решение с помощью Android SDK Tools версии 18.1.1, но продолжал терпеть неудачу из-за ошибки:
taskdef class com.android.ant.SetupTask cannot be found

В конце концов, я сделал следующее:

rm build.xml
android update project -p .
  • Если у вас нет инструментов SDK в вашем PATH, вам нужно будет использовать полный путь к инструменту Android, например, в Windows: C: \ Android \ sdk \ tools

Это создало новый build.xml, который совместим с текущими инструментами SDK и, похоже, автоматизирует большую часть ручной работы, описанной в ответе barmaley.

После этого я смог запустить ant release, который позаботился о создании и обфускации результирующего файла .apk из коробки.

Чтобы автоматизировать обфускацию с помощью ant, вам необходимо:

  1. Включить обфускатор Proguard (очевидно)
  2. Создайте файл ant.properties и заполните его соответствующими параметрами key.store (подробности см. В этом ответе SO).
person AVIDeveloper    schedule 15.11.2013

Для процесса обфускации proGuard требуются файлы .class, поэтому вы не можете запустить Ant до сборки IDE (.java) или после (упакованный .dex).

Посмотрите этот пост, где объясняется, как добавить шаг proGuard в вашу глобальную сборку Ant:

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

Если вы действительно хотите использовать сборку IDEA, вы можете попробовать следующее.

  • После сборки IDEA распаковать apk с помощью apktool.
  • Преобразуйте файлы .dex в .class с помощью dex2jar
  • Запустите proGuard, как показано в предыдущем посте.

Извините, что я не прикрепляю вам ссылки на apktool и dexjar, но поскольку я новичок, я не могу разместить более одной гиперссылки.

person Felipe Fernández    schedule 26.01.2011
comment
Знаю, но для Ant нужен только build.xml :) - person Barmaley; 28.01.2011