Proguard is a Java shrinker and obfuscator. It reads java .jar files and writes them back with a significantly smaller size. This is achieved by various optimizations, elimination of unused code, and renaming of classes, methods and members to shorter (1-letter) names. Proguard is a good and very useful tool for general Java projects.
What about using Proguard with Android applications? Well.. it works great!
Android compiles Java source files to Java bytecode. The Java bytecode is next converted to Dalvik bytecodes by the “dx” tool. In between these two step we can apply Proguard to shrink the Java bytecodes. The result is impressive: a reduction of about 30% or more in .apk size! This results in the application downloading faster, taking up less space on the limited flash storage on the phone and starting up faster. The only drawback? it makes analyzing an application crash more difficult, as the stack trace of an exception has only the new short names and thus is pretty obscure.
I prepared this simple shell script which illustrates the commands needed for a complete Android build including proguard shrinking. It was tested with Android SDK 1.6.
#!/bin/bash NAME=Calculator SRCS=src/calculator/Calculator.java #optional, if you use external.jar libraries LIBS=libs/arity-1.3.4.jar SDK=/path/to/android/sdk PROGUARD=/path/to/proguard/lib/proguard.jar KEYSTORE=/path/to/android.keystore KEYALIAS=andkey PLATFORM=$SDK/platforms/android-1.6/ AAPT=$PLATFORM/tools/aapt DX=$PLATFORM/tools/dx AJAR=$PLATFORM/android.jar PKRES=bin/resource.ap_ OUT=$NAME-unalign.apk ALIGNOUT=$NAME.apk set -e #exit on error mkdir -p bin/classes gen $AAPT package -f -m -J gen -M AndroidManifest.xml -S res -I $AJAR -F $PKRES javac -d bin/classes -classpath bin/classes:$LIBS -sourcepath src:gen -target 1.5 -bootclasspath $AJAR -g $SRCS java -jar $PROGUARD -injars $LIBS:bin/classes -outjar bin/obfuscated.jar -libraryjars $AJAR @proguard.txt $DX --dex --output=bin/classes.dex bin/obfuscated.jar apkbuilder bin/$OUT -u -z $PKRES -f bin/classes.dex jarsigner -keystore $KEYSTORE bin/$OUT $KEYALIAS zipalign -f 4 bin/$OUT bin/$ALIGNOUT
The contente of the file “proguard.txt” referenced above, which contains the Proguard options, is:
-keep public class * extends android.app.Activity -dontskipnonpubliclibraryclasses -optimizationpasses 2 -printmapping map.txt -flattenpackagehierarchy
Treat this script more like a guideline to the series of commands needed for a full android build, and adapt it to your needs. Disclaimer: use at your own risk and re-test your proguarded apk thoroughly to find any problems introduced by shrinking.
Building a shrinked, optimized, signed and zipaligned .apk is only useful for the release version of an application. For debug builds where size and optimization is not important you should use the normal Android build without proguard.
Given the great usefulness of applying Proguard on Android apps, I would really like to see Proguard integrated with a future version of the Android SDK — that would assure a much wider adoption of apk shrinking.
As an example, Proguard shrinked my already tiny application Arity Calculator from 45KB to 30KB.. Enjoy Proguard on Android!