What is Proguard?

Proguard minimizes your code by taking recurring method names, field names, and class names and renaming them with smaller names. It also removes any unused code from your APK.

Why use Proguard?

With names minimized and unused code removed your APK is much smaller. Users tend to like smaller APK sizes as they download quicker and eat up less data. Since proguard changes the names of your methods it is harder for someone to decompile your code to determine how it works and possibly find weaknesses. Change your code like this is called obsfuscation.

Where does it come in?

Since we only need these security features during distribution like in the Google Play store, proguard is only used for release builds. Luckily gradle takes care of this for us.

Using Proguard

This tutorial assumes you are using gradle to build your project. There are links to corresponding files in the sample project.

The first thing to do is tell gradle that we want to use proguard for our release buildType.

You can run proguard now without any further configuration but lets tell proguard a little more about what we want. Proguard gets its configuration from a file in the project called proguard-rules.pro. Lets modify it to tell proguard we want to keep the line numbers in our stacktraces. Modify the contents to looks like this:

-keepattributes SourceFile,LineNumberTable

Now we are ready to build the sample project and see it run.

# in project base
./gradlew build

in the output you should see :app:proguardRelease which happens after the Java is turned into .class files and before the .class files are turned into dex code.

Proguard has also created some text files for us. We will use these text files to turn the obsfuscated stacktraces into readable stacktraces. The created text files are found in app/build/outputs/mapping/release/.

The methods have been renamed from subMethod & subSubMethod to i & j by proguard. See the full file here. The onClick method is called when the button is tapped.

So now lets de-obsfuscate this stacktrace. Take the text from ADB and save it to a file. I have used stacktrace.txt. The proguard tools are found in $ANDROID_HOME/tools/proguard/bin/. We will be using the mapping.txt file that proguard produced in the build.

$ retrace.sh mapping.txt stacktrace.txt

The outputted stacktrace will contain the de-obsfuscated stacktrace. In my example:

Common pitfalls

One common mistake is that proguard doesn’t know about any reflection you are doing in the code so it may rename some methods that you are invoking programmatically. You can tell proguard to skip file by adding it to proguard-rules.pro

-keep class com.github.browep.MainActivity

Save the mapping.txt file for each release build. Without it you cannot de-obsfuscate your code. Consider adding to your source repository.