Skip to main content

Aapt2: Please don't delete me!

By making one weird change in aapt2, we sped up our build by 45 seconds. Developers love that stuff.

This is the second in a three part series about adventures with aapt2, Android's resource compiler / optimizer. You can read the first bit and get more context here.

Proguard is an optimizer that many Android apps use. It can do nifty things like removing unused code and resources, inlining things that have no real reason to be in separate methods, and even obfuscating symbols so you can pretend like nobody will ever be able to figure out what your clever code is doing. In modern Android, the r8 shrinker has a similar function, and is driven by proguard configuration files.

However, r8 / Proguard can't always figure out if something is used, or sometimes optimizes more aggressively than you'd like. Configuration directives can be used to tell it to keep things that would otherwise be removed. aapt2 has options that let it emit configuration files for resource related code. 

I used a profiler to look at the performance of aapt2 on our codebase, and it turned out that a significant chunk of the increased time was being spent in one function, aapt::proguard::CollectLocations(), which is part of the machinery that generates these rules. In particular, it was spending a lot of time generating rules for the --proguard-conditional-keep-rules option, which removes resource ids that don't match certain usage patterns known to be used in layouts.

It turned out that we didn't have that option turned on in our codebase (we use other tools for optimizations like this), so the extra work that was being done here was being thrown away anyway. I wrote up my findings and sent a patch upstream, which I think is always quite a polite thing to do when you discover an easily fixable issue. This immediately sped up our round trip build time by about 45 seconds. Many thanks to the folks at Google for quickly accepting this upstream!

But I was still not happy with how long developers had to wait for aapt2 to do its thing... Stay tuned for another optimization in the next post.


 

The next blog post in this series talks about another big performance optimization that came from reducing the number of languages we use in dev builds..

Comments

Popular posts from this blog

Java Blooper #2: Must be a Better Way...

The post you're reading is ancient, and yet slightly inexplicably popular :) I've recently started blogging again in 2020 with some fresh content. Check out some of the new topics about blogging again, dynamic method invocation, and aapt2.It's Monday, which means it's time for another blooper... What's wrong with this code? boolean hasThing( List things, Thing thing ) { for ( int i=0; i < things.size(); i++ ) { if ( thing.equals( things.get( i ) ) ) { return true; } } return false; } Update: Minor edit to add missing parenthesis from if statement that got "lost in translation" en-route to the blog :)

Configuring Mac OS X Terminal

The post you're reading is ancient, and yet slightly inexplicably popular :) I've recently started blogging again in 2020 with some fresh content. Check out some of the new topics about blogging again, dynamic method invocation, and aapt2.I recently installed Leopard (Mac OSX 10.5) on a new mac. There are a few factory settings I usually change on a new installation, although by far fewer than I do typically with Windows. One of them is the default keyboard configuration for Ctrl+Left Arrow, Ctrl+Right Arrow, Page Up, Page Down, Home, and End in Terminal. The default settings drive me a bit potty since I'm used to using Linux and emacs every day at work.Changing them is easy, fortunately. Just visit Keyboard under Settings in Terminal->Preferences, and modify the following keys, so that their action matches the value shown. You can edit the keystroke for an item by double clicking on it, selecting "send string to shell", and typing the indicated keys.KeyActio…

Java Blooper #1: Ternary Insanity

The post you're reading is ancient, and yet slightly inexplicably popular :) I've recently started blogging again in 2020 with some fresh content. Check out some of the new topics about blogging again, dynamic method invocation, and aapt2.From time to time, we all write code that could be clearer. Sometimes in the rush of solving a problem, we don't pay attention to the micro details of the code flowing from our fingertips. Other times, we refactor some existing code, and don't necessarily take the opportunity to clean up as much as we could.I find it useful sometimes when reading code to think about whether it could be rewritten in a more straightforward way, and if so whether any lessons can be learned about writing tight and expressive, and most importantly, readable code.Over the next few weeks, I'm going to blog weekly examples of some Java code bloopers that I've seen. All the examples are real and have been observed "in the wild". However some…