ProGuard, a code optimization and obfuscation tool provided as part of the Android SDK, can be a double edge sword — it presents bootstrapping challenges but when applied correctly, provides tremendous benefits! At Crashlytics we’ve spent a lot of time leveraging the power of ProGuard to develop lightweight libraries to help app developers ship awesome products — in particular, we use these four features in our day-to-day development.


As your codebase grows and becomes more full featured, it’s important to keep a small binary in mind. Reducing the size of the APK can be extremely advantageous, since large binaries are much less likely to be installed in poor network conditions or on older less powerful devices.

It’s been well publicized among the developer community that the Dalvik Virtual Machine is memory limited to 64k methods. With this restriction, ProGuard can help provide a buffer as you consider which measures to take to reduce your code size. Removing unused code, which likely exists in a 64k method project, enables your development team to work on features unimpeded by technical limitations, while refactoring or external class loading is considered.

Even though shrinking is advantageous, simply identifying unused code to remove is a good practice. By using the printusage flag in Proguard.cfg, your configuration file, ProGuard will list the unused code to allow for proper code maintenance and cleanup.

 1 # This is a configuration file for ProGuard.
 2 #
 4 -dontusemixedcaseclassnames
 5 -dontskipnonpubliclibraryclasses
 6 -verbose
 8 -printseeds seeds.txt
 9 -printusage unused.txt
10 -printmapping mapping.txt


With tools available to extract the contents of APK’s, deodex, and read the class files, it’s important to obfuscate to protect the proprietary aspects of your codebase. ProGuard generates a mapping file that allows you to map the stack traces of obfuscated code to actual methods.

Original code:

 1 package;
 3 public class Data
 4 {
 5    public final static int RESULT_ERROR = -1;
 6    public final static int RESULT_UNKNOWN = 0;
 7    public final static int RESULT_SUCCESS = 1;
 9    private final int mId;
10    private final int mResult;
11    private final String mMessage;
13    public Data(int id, int result, String message) {
14       mId = id;
15       mResult = result;
16       mMessage = message;
17    }
19    public int getId() {
20       return mId;
21    }
23    public int getResult() {
24       return mResult;
25    }
27    public String getMessage() {
28       return mMessage;
29    }
30 }

Code obfuscated by ProGuard:

 1 package;
 3 public class a
 4 {
 5    private final int a;
 6    private final int b;
 7    private final String c;
 9    public a(int paramInt1, int paramInt2, String paramString)
10    {
11       this.a = paramInt1;
12       this.b = paramInt2;
13       this.c = paramString;
14    }
16    public int a()
17    {
18       return this.a;
19    }
21    public int b()
22    {
23       return this.b;
24    }
26    public String c()
27    {
28       return this.c;
29    }
30 }

By automatically collecting the mapping files on build, Crashlytics streamlines the deobfuscation process of your code and intelligently prioritize stack traces to make your debugging process effortless.


Repackaging allows ProGuard to take externals jars and class files and move them to a single container with a common java package location:

 1 # com.example.networking contains the networking level
 2 # com.example.database contains the persistence level
 3 # repackage low level services into common package for simplicity
 4 -repackageclasses "com.example.internal"
 6 # com.example.public contains public interfaces
 7 # ignore these in repacking
 8 -keep public class com.example.public.* {
 9    public *;
10 }

For those of you building libraries, repackaging is extremely helpful if you choose to show a simple interface to third party developers while keeping a maintainable and well structured project hierarchy in the source repository. This can also be useful in organizing lower level packages while exposing well defined interfaces!


Optimizing works on compiled classes to implement many small optimizations based on the java version. By default the proguard-android.txt that ships with the Android tools has optimizations turned off, but the proguard-android-optimize.txt has the presets if needed.

 1 # Optimizations: If you don't want to optimize, use the
 2 # proguard-android.txt configuration file instead of this one, which
 3 # turns off the optimization flags.  Adding optimization introduces
 4 # certain risks, since for example not all optimizations performed by
 5 # ProGuard works on all versions of Dalvik.  The following flags turn
 6 # off various optimizations known to have issues, but the list may not
 7 # be complete or up to date. (The "arithmetic" optimization can be
 8 # used if you are only targeting Android 2.0 or later.)  Make sure you
 9 # test thoroughly if you go this route.
11 -optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
12 -optimizationpasses 5
13 -allowaccessmodification
14 -dontpreverify

Optimizations provide performance improvements for language operations. However, there are known incompatibility issues with various Dalvik versions, so we encourage a thorough review of the code base and device target demographic before enabling.

Beyond leveraging these four core features of ProGuard, we crafted several strategies for those of you looking to build lightweight apps/libraries and optimize your interaction with ProGuard.

Improving Build Times

Adding ProGuard to the build process can slow down build time, so it’s important to minimize the amount of code ProGuard needs to examine. This is vital when considering third party libraries, like Crashlytics, that have already been processed by ProGuard — it’s just a waste of CPU to reprocess with ProGuard again, and it’s much slower!

We thought it would be valuable to estimate the improvement in build times when preprocessed, third party libraries are ignored in ProGuard. Using the Crashlytics library as an example, we conducted numerous runs with internal test apps across various sizes. We found that build times improved by up to 5% when the Crashlytics package is ignored. But that’s just one library that is already ultra-lightweight. Imagine the build time improvements for apps leveraging additional libraries — it can be tremendous.

To avoid processing a library that may have been preprocessed, simply add the following to Proguard.cfg:

1 -libraryjars libs
2 -keep class com.crashlytics.** { *; }

As obfuscation is usually done for security, if using an open source library, there may be no reason to obfuscate it. By following a similar pattern as listed above, processing can be further reduced ultimately improving build time. The Android support library is a great example:

1 -libraryjars libs
2 -keep class** { *; }
3 -keep interface** { *; }


Using reflection in Android is highly discouraged for many well known reasons, including performance and instability in changing APIs, however, it can be quite useful for Unit Testing. Common use includes changing the scope of methods to set test data or mock objects. If you’re using ProGuard during development build to obfuscate, it’s important to understand that when a method or class name is changed, string representations of them are not. When designing testable interfaces, if tests are run on a device using a build that has been processed by ProGuard, this will cause method not found exceptions.

Library development

Additional complexity is introduced when developing libraries that are processed with ProGuard, both when they are distributed and when the app developer runs the process. When the code is obfuscated twice, it is much more challenging to track down bugs as two mapping.txt files would be required to de-obfuscate the stack trace. To avoid processing these libraries with ProGuard a second time, be sure to follow our steps in section above on improving build times!

For those of you building libraries, you may have encountered more challenges with ProGuard because in any sufficiently complex project, the possibility for custom ProGuard rules exists. We recommend not requiring custom ProGuard rules because the library can break if a different set of rules is applied after a custom set. If custom rules are required, be sure that those using your library include any custom ProGuard rules in their own config file. This will ensure compatibility between your library and the app!

1  # Custom Rules
2 -keep class com.example.mylibrary.** { *; }

Ever since Crashlytics was born, we’ve made it our mission to make developers’ lives easy. We hope that these strategies will help you build the next groundbreaking Android app/library and perhaps in the process, make a dent in the universe ;)

External Resources

View More


If you’re anything like the rest of the world you’ve probably already proclaimed that your new diet didn’t apply to Super Bowl Sunday, or Awards Season, or the Polar Vortex, or winter. Which is fine! Life’s too short not to eat nachos. But if your resolution had anything to do with improving your apps’ stability to delight even more users, no worries — we’ve got good news for you!

We love supporting you to help minimize crashes and improve user experience, which is why last month we were heads down upgrading our stack traces and UI performance. Now you can tackle those hard to catch bugs with our high-performance dashboard, even easier-to-digest crash reports for both iOS and Android, and a slew of usability upgrades.

Faster, Better, Stronger
Isn’t it awesome when your apps and dashboards render at lightning speed? Our crash reporting dashboard is already returning tons of useful information in under a few seconds, but we wanted more. By more efficiently parsing protobuf and stopping the browser from freezing on render, our new UI now renders stackframes up to 181x faster with nearly 55% reduction in memory!

Here’s a performance comparison between our original and newly optimized UI across the major browsers:

Powerful, Shareable Stack Traces

To make stack traces even more useful, we now allow easy copying & pasting of your raw stack traces, so you can share them seamlessly with your team even outside of our shareable crash reports feature. We also upgraded our iOS SDK to record Objective-C selectors, when possible. By including the selector being dispatched during crashes in objc_msgSend, developers can track down certain classes of crashes and gain additional context in certain cases that can be otherwise inscrutable.

From our friends at Evernote:

Every developer should be using Crashlytics. Except my competitors. It provides more crash information than any similar tool.

John Knox,

With the rapid growth of developers using Crashlytics for Android, we knew we needed to support this growing community and provide Android stack traces in their most familiar context. We now present these stack traces in a way that’s in line with the traditional Java counterpart.

Comprehensive & Interactive

Sometimes it can be overwhelming to scan through long lists of threads in your crash reports — almost as overwhelming as grocery shopping for that juice cleanse you had planned for the start of the New Year! With these new upgrades, we took this chance to enhance the UI controls for maximum readability. We added a breakpoint-like indicator to highlight the most important frame so it is identifiable at a glance.

We also added new controls that make it even easier to understand which frames have been hidden and how to expand the collapsed threads.

We couldn’t be happier to get the new stack traces and UI upgrades into your hands and help you to continue to build awesome apps. We hope these enhancements will help you stick with at least one of your resolutions this year. Log in or sign up for Crashlytics and send us your feedback; we’re always listening!

Already have an account? Log in here.

View More


Crashlytics Look Back at 2013

2013 was a year filled with excitement, innovation and disruption. Apple introduced the iPhone 5S, Google announced an IDE built just for Android developers, and the world rolled their eyes as words like selfie, twerk and jorts were added to dictionary!

It was exactly a year ago today that we joined forces with Twitter. Since the acquisition, not only did we enhance features, functionality and improve your experience with Crashlytics, we also had some pretty exciting personal achievements — our first kegerator, 4 Crashlytics babies, and 24 new employees (p.s. – we’re hiring)!

Here’s a look back at how things shook out for us in 2013.

Crashlytics Look Back at 2013 Infographic


View More

We know you’ve been busy untangling the lights, posing for the always entertaining family photo, losing your mind finding a parking spot at the mall, all in an attempt to track down that nearly impossible to find gadget that’s on everyone’s list this year. Well, no need to wear your pj’s inside out and backwards, because our updates this month will make you feel like school’s been cancelled and it’s time to play!

This month, we’ve been busy delivering you the holiday gifts you won’t find under your tree! Back in November we launched a new version of Crashlytics for Android SDK, along with a slew of enhancements to our IDE plugins and usability upgrades. Finishing the year out strong, we crafted a dozen gifts just for you: upgraded data visualization, enhanced navigation experience, multiple support enhancements to the IDEs and platforms — and more!

Lightweight, Cutting-Edge Data Visualization

We first upgraded our data visualizations by leveraging the latest, much lighter weight D3 library. To give you an even more interactive experience, we revamped the metrics UI on our issue list page and updated the time series on the issue details. We also upgraded the metrics summary data that displays device and OS details, with fully interactive pie and bar charts.

We believe that developer tools should be beautiful and intuitive — not like that failed attempt to recreate Grandma’s famous fudge! Our new graphs and charts flow naturally with our upgraded design theme. We also updated the alert center where alerts for new comments and issues now use our standard UI library. This is all while enhancing the accuracy of our realtime service in improving the delivery of information for new issues, comments, and service hooks verifications!

Effortless, Cross-Device Navigation

To make it easy for you to navigate through different platforms and devices, we revamped the issue’s metrics dashboard and broadened the date range so you can view up to 30 days worth of crashes per issue. We also reduced the number of selector options by removing the old Alert Center’s app switcher.

We upgraded the stack trace on the issue details and session summary pages by removing the separate section that contained the exception and memory address and placing that information inside the crashed stacked trace header. To better denote the crashed header’s significance, we highlighted it in blue so you can spot it with ease, just like Rudolph’s red nose!

More Powerful, Multi-Platform Support

We didn’t waste any time adding support for the latest release of IntelliJ 13, including support for Android Gradle projects. We also updated our Gradle plugin to support a breaking change in the latest version of Google’s Android Gradle plugin, which prevented any broken builds that would’ve been caused by Google’s change in the default flavor capitalization.

For our Eclipse IDE plugin, we drastically improved the efficiency of icon prefetching. Outside of the Android platform, we also improved the application icon support for iOS 7, which ensures that your latest application icons will be located and automatically updated in our web dashboard and Mac app!

Here’s our internal changelog:


  • Improved application icon support for iOS 7.

Mac App

  • Resolved minor issue with deleted applications.

IDE Plugins

  • Built support for IntelliJ 13.
  • Enhanced efficiency of icon prefetching for Eclipse plugin.
  • Fixed minor bugs that caused the plugin window to flicker and disappear when first opened.
  • Resolved issues that caused Eclipse Kepler to occasionally halt during startup.


  • Overhauled Issue’s metrics dashboard and increased date range for customers.
  • Reduced selector options and implemented new standard UI library into alerts for new comments and issues.
  • Upgraded data visualizations to D3 and updated time series on the issue details page.
  • Enhanced metrics summary data with interactive pie and bar charts.
  • Improved alert center with new CLS UI.
  • Boosted performance of realtime service on returning information associated with new issues, comments, and service hooks verifications.
  • Updated stack trace on the issue details and session summary pages.
  • Moved exception and memory address information of a crashed session inside the stacked trace header with header highlight.

This year has been full of fun and excitement and we can’t wait to continue to celebrate with you into next year! While we won’t be squeezing down any chimneys to fill your stockings with treats, we hope these upgrades and enhancements will keep you smiling through the holidays. Happy holidays from our Crashlytics family to yours :-)

View More


It’s that time of year! Time to hang with the fam, write code, and enjoy an ice cold winter lager. All while making sure you’re dressed to impress for the inevitable run in with your old high school flame…

As Thanksgiving approaches, we have a ton of updates to share that are sure to distract you from the very obvious fact that Cousin Sam burned off his eyebrows in the deep fried turkey practice round that went down last weekend! This month, we bring you a new version of the Crashlytics for Android SDK, user experience enhancements to our IDE plugins, and usability upgrades to our web dashboards.

And just to recap–before you caught Grandma putting more wine in her glass than the gravy pan (go Granny!), and even before your little sister brought her tattoo-covered boyfriend home from college — back in October we shared two major announcements back to back: Crashlytics for Android Studio and Crashlytics Real-Time Search.

Performance & Responsiveness

We’re excited to have shipped v1.1.5 of our Android SDK with some serious performance upgrades! (If only there was a way to boost your own performance after you fall into that inevitable Thanksgiving Day food coma).

We tweaked our starting logic to move an extra blocking call off the main thread, reducing our SDK start time by over 75%, so you can get Crashlytics up and running even more efficiently — similar to how that extra cup (or 3) of coffee will have you nailing those Black Friday deals better than ever! To make the Crashlytics logger more useful, we now log priorities and tags to your crash reports as well as the Android logger. We also boosted crash processing efficiency by eliminating unnecessary process data collection and reduced the prioritization of Crashlytics threads to free up even more resources for your app.

When mom asks why we showed up empty handed on Thursday, we’ll have a good excuse: we’ve been busy deploying several updates to our Android IDE plugins to enhance the user experience! These include smart drawing of our plugin to better handle non-IDE windows that have focus, and an even smoother responsiveness of the organization selection screen, which now loads network data asynchronously.

Seamless & Intuitive

For those of you asking for access to the raw stack traces, we heard you loud and clear — even over the sounds of the too-soon holiday music that seems to be glaring from every car stereo anywhere. Our web dashboard now gives you the power to see and copy a raw representation of exceptions and threads. This feature is especially beneficial to our Android developers because you can also use the raw stack inside your IDE, so debugging crashes became easier than ever.

After launching shareable crash reports in September, we added read-only comments to these reports. Now even developers without Crashlytics accounts can view these notes, which can include useful information for collaboration with your team (e.g. JIRA URL). We get it — even if you remembered to put elastic waist pants on before you sat down to eat you still need help from the whole extended family to make a dent in that bird!

To enhance overall usability, we completely revamped the Issue’s session page, along with newly added drop down menus for users to easily navigate between their organizations and applications.

Here’s our internal changelog:

Android SDK

  • Reduced SDK start time by over 75% by eliminating a blocking call during exception handler initialization in Crashlytics.start().
  • Enhanced Crashlytics.logException(Throwable) to log a warning via Log.w() and immediately return on null input.
  • Crashlytics.log(int priority, String tag, String message) now logs the priority and tag to Crashlytics reports as well as the Android logger.
  • Removed collection of unused process data to improve crash processing efficiency.
  • Explicitly set all Crashlytics background threads to THREAD_PRIORITY_BACKGROUND to defer CPU resources to the application.

IDE Plugins

  • Fixed a bug preventing the Crashlytics SDK from being pulled into Android Studio automatically while adding an application.
  • Pushed a non-critical fix to our plugin updater that prevents multiple updates between IDE restarts.


  • Enhanced the UI of our modals and notes section as well as added the ability for users to filter out versions directly from the dropdown menu.
  • Added raw stack traces so developers can now see and copy a raw representation of the exceptions and threads.
  • Added read-only comments in shared crashes so notes are visible to team members who got the shared link but didnt have a Crashlytics account.
  • Revamped UI for Modals and Notes.
  • Added filters to Dropdown menus.

Thanksgiving 2013

  • Won the office-wide “Movember” contest (Tom Selleck truly is an inspiration).

It’s been quite a busy fall season for us but we look forward to shipping even more features before the year’s end. In the meantime, we’ll catch up with you guys on the other side of the holiday — save us some leftovers! Now, back to googling “Thanksgiving puns”…I mean…writing code ;)

View More