Search code examples
androidproguard

Easy mode for using Proguard in Android


When prepare to release the Android app, we would use Proguard to obfuscate the code which may break the app.

So once some error occurs, we modify that and build-release-test again and again, is there a simple way to do that?

Also, is it possible to see the obfuscated code directly in Android Stuido?


Solution

  • Retracing

    Retracing is what makes the obfuscated stack trace human-readable by replacing obfuscated names to the ones used in original source. In order to be able to retrace, make sure to save mapping.txt for every build you are about to test or send to someone. Mapping is unique for every build process.

    Mapping can be found in

    appModule/build/outputs/mapping/release/mapping.txt
    

    For retracing, there is a convenient tool named proguardgui, found in

    $ANDROID_HOME/tools/proguard/bin/proguardgui.sh
    

    (*.sh for UNIX systems, for other platforms expect different extension).

    Choose "ReTrace", add a mapping.txt (make sure to use mapping.txt that was generated for that apk build) and paste the obfuscated stack trace into window. Press "ReTrace" on bottom right corner and you should get that stack trace with deobfuscated names.

    Here's a screenshot with sample input I found on the Internet enter image description here

    Decompiling

    Also, is it possible to see the obfuscated code directly in Android Stuido?

    No, but you might see the code by converting dex to jar and decompiling it.

    dex2jar myapp.apk
    jd-gui myapp-dex2jar.jar
    

    dex2jar github page.

    jd-gui from github page.

    Practices I use to follow

    What works for me is whenever I add a library I add a proguard config for a library (usually provided by library developer).

    There's also a project called android-proguard-snippets, thought they are mostly outdated, so make sure to check from library developer first.

    For easy management, I use to split the proguard config for every library in a separate file. Below is a snippet from one of my build.gradle buildTypes for release

    proguardFile getDefaultProguardFile('proguard-android.txt')
    proguardFile 'proguard-dart.pro'
    proguardFile 'proguard-parceler.pro'
    proguardFile 'proguard-retrolambda.pro'
    proguardFile 'proguard-rules.pro'
    proguardFile 'proguard-rx-java.pro'
    proguardFile 'proguard-support-design.pro'
    proguardFile 'proguard-support-v7-appcompat.pro'
    

    For objects used in Firebase serialization, add @Keep annotation.

    For fields used by Gson, add @SerializedName annotations or use @Keep on an object.

    Whenever I use reflection (or Animators, which are technically the same) I make sure to add proguard rule to keep the code accessed by reflection just after I write such code. In the end there will be probably nothing to fix.