Recent Changes‎ > ‎

    ProGuard Improvements

    posted Feb 27, 2012, 4:08 PM by Tor Norbye   [ updated Feb 27, 2012, 4:21 PM ]
    ADT 17 brings a number of improvements to the ProGuard integration.

    First, we've updated the bundled version from 4.4 to 4.7. Along with a number of other fixes and enhancements (see the ProGuard documentation at http://proguard.sourceforge.net/), this fixes the dreaded "Conversion to Dalvik format failed with error 1" error some users have experienced. We've also updated the code which launches ProGuard, which should hopefully address a number of "spaces in paths" issues.

    Second, we've changed the way configuration files are handled.

    In previous releases, when you created a new Android project in ADT, we would copy a default "proguard.cfg" file into your project. This file contained a number of rules necessary for using ProGuard with Android, such as disabling certain optimizations not compatible with Android, adding "keep" rules to prevent shrinking methods only referenced from XML, etc.

    However, over time, we've both discovered bugs in the default configuration, and of course as the Android API keeps evolving new additions to the rules are necessary as well. The problem we've run into is that users now have stale copies of the old proguard.cfg file in their projects. We've added some lint rules to detect some known bad patterns -- however, when users start editing and reorganizing their own proguard configuration files it gets very difficult to determine if a file is "up to date" with respect to the current recommendations.
    Furthermore, most users don't want to read the ProGuard documentation and tweak the configuration -- they just want to get their applications shrunk and obfuscated before uploading it to the Market.

    Therefore, as of ADT 17 we've split the configuration file in two halves:
    • A "default" set of rules for Android
    • Project-specific flags
    The critical point is that the default set of rules is no longer copied into the project. It resides in the tools install (specifically tools/proguard/proguard-android.txt), and gets updated along with the rest of the tools.

    The project specific flags are any local additions to the ProGuard configuration, such as specific -keep flags you want to add that are specific to your own code. By default, this file is named proguard-project.txt in the root of your project. We switched the file extension from .cfg to .txt since these are really just text files, and by changing the file extension you can just double click on the files in Eclipse and edit the files. (With .cfg, or the .pro extension used in the ProGuard documentation, Eclipse would open a native editor, which often would be unrelated to ProGuard; in my environment .pro files opened in an editor for editing Prolog files.)

    Note that this behavior is not mandatory. You can continue to completely specify the complete ProGuard configuration in your project. 

    To make this all work, we've changed the meaning of the proguard.config property in your project.properties file. In older versions, the way you would enable ProGuard shrinking and obfuscation was to define proguard.config=<path to config file, usually just proguard.cfg>.

    As of ADT 17, the proguard.config property refers to a path instead, so you can specify as many configuration files as you want. These are all joined together by ProGuard. By default, ProGuard is turned off, but the project.properties files for new projects contain the following comment block:

    # To enable ProGuard to shrink and obfuscate your code, uncomment this
    #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

    (You can use ${sdk.dir} and ${user.home} in these paths to avoid putting absolute paths in your project file, which is particularly important since this project.properties file typically is checked into version control.)

    So, to enable ProGuard in the default way, simply uncomment the above line. You'll pick up all the default Android ProGuard configuration flags from the tools directory, and when we update the tools to fix bugs or update the configuration based on Android changes, you'll automatically be using them.

    If you want to completely control your ProGuard configuration, simply specify just your own configuration file instead. Note that ProGuard typically doesn't let you subtract flags, so if you disagree with one of the default flags, you'll need to copy the global configuration into your own files and remove the lines you want to disable. One such flag you might want to consider is the -dontoptimize flag. The main reason developers use ProGuard is for the shrinking and obfuscation aspects (to make downloads and runtime sizes smaller, and to keep the code somewhat private, and there are performance benefits to symbols as well). Dalvik performs many of its own optimizations, and some of the optimizations performed by ProGuard are incompatible with Dalvik, so to avoid hard-to-figure-out bugs (and because the net performance gain is usually small), the default configuration turns off optimization. If you want this, look at the commented out optimization flags in the default file, copy the configuration to a local file and remember to test carefully. And also make sure that you regularly check that your local configuration is up to date.

    The default configuration file in ADT 17 has been updated a fair bit, so if you're not going to be using it directly, you might want to compare your own copy with the new copy to see if you're missing anything. We've added some more comments to explain the various flags.

    Now, everything explained above refers to new projects created from this point forward. What about existing projects?

    Don't worry, we don't touch them. Everything continues to work just as it does today; none of your flags are changed automatically. However, we suspect that most developers are not using a deliberate configuration, they're just using what they got when they created their project, and they might not be aware that their configuration is out of date. To help users become aware of this whole issue, we've added a new lint rule to detect this scenario:
    Hopefully this will contain enough information to make it obvious how to edit your project.properties files to link to the default Android configuration file and any remaining local flags.  This lint rule only kicks in if you've actually enabled ProGuard, such that it won't bother all the developers who have a default proguard.cfg file in their project because it was created for them, but where it is not being used.

    Finally, note that the proguard.config property is a path. You can specify more than just these two files. If you want, you can also use the ${user.home} flag to reference to your home directory. Thus, you can have the "global" Android defaults in ${sdk.dir} as shown above, and your own "per-user" flags (shared between all your projects) in ${user.home}, and finally any flags that really are project specific in the project using just a project relative path.
    Comments