Skip to content

Android and Proguard, the shrink recipe

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!

{ 6 } Comments

  1. Akshay Dashrath | 2009-11-17 at 14:11 | Permalink

    Hey,

    I’m working on performance profiling of scala application on Android and was trying to get proguard to strip my scala application of unnecessary classes. However I’m using eclipse in order to compile my code etc. and was having a spot of trouble following your instructions in using pro guard to strip the unnecessary classes. In your command

    java -jar $PROGUARD -injars $LIBS:bin/classes -outjar bin/obfuscated.jar -libraryjars $AJAR @proguard.txt

    I’m a bit lost with the $LIBS:bin/classes , is the :bin/classes the folder where your compiled .class files exist?

  2. Mihai Preda | 2009-11-19 at 17:28 | Permalink

    Yes, that’s where the compiled .class files are. Look at the previous line, “javac -d bin/classes”, that’s who put them there.

  3. Akshay Dashrath | 2009-11-22 at 08:22 | Permalink

    Every time I strip the program of the unnecessary classes it does’nt seem to run, It installs fine but eventually I get a force close error :( .

  4. Matt | 2010-07-20 at 15:22 | Permalink

    Hi there, I just posted a blog entry about how to integrate ProGuard with your Android build.

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

  5. Free android apps | 2010-08-12 at 21:36 | Permalink

    I followed the installation process very clearly and yes, it installs perfectly but then, I got the same result with Akshay above. What do you think is lacking?

  6. ydant | 2010-08-25 at 02:06 | Permalink

    Follow logcat and it’ll probably help point you out what is not working properly. In my case, it was event handler names defined in the XML (when obfuscated, Android can’t find them), and the BroadcastReceiver and Application classes needing exclusions just like the Activity exclusion in the example proguard.txt.

{ 1 } Trackback

  1. [...] I said in my previous post about using Proguard with Android apps, the only drawback of Proguard is that the stack-traces (following an application crash) become [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *