Skip to main content

Aapt2: Tower of Babel

OK, we'd fixed a bug that brought us back to our baseline build speed with aapt2. But could it be made even faster?

This is the final part of a three part series about adventures with aapt2, Android's resource compiler / optimizer. You can read the intro bit and get more context here. The second post explained a small fix that resulted in a nice performance win.

Big Android apps like the hypothetical ones from that hypothetical company that I hypothetically work for tend to contain a lot of strings that are translated into hypothetical languages (er, maybe I didn't need that last hypothetical). However, during the compile-run cycle, most developers are usually working with a single language. This is not to understate the importance of testing with a variety of languages, but it's reasonable and normal to restrict things somewhat in dev builds for developer efficiency reasons.

There are really a lot of strings in a lot of languages in some of these hypothetical apps. Like really a lot. I wish I could say how much, but think about what you'd consider a lot, then add some more to it. 

My profiling from finding the previous issue had shown me that aapt2 was spending an awful lot of time dealing with the huge number of strings we were throwing at it. But most of the time, developers really only cared about a tiny fraction of these strings in developer builds. I spotted a friendly looking option in that looked like it might be quite useful:

So, I was thinking if maybe I could just do something like this in our dev builds, things would be waaaay faster:

  aapt2 link -c en ...

Whelp, it didn't work! Erm.

So it turned out that the way aapt2 link processes the -c option is as a post filter - it still processes all the input resource files containing strings in every configuration. One way we could get around that is to filter these resources out at compile time so we never pass them into the link phase. Because of some particular complexities of our source / build system, that'd mean copying or creating symlink farms of resources. 

I ended up instead just patching aapt2 to make it respect -c as a pre-filter instead. With this change, it completely ignores inputs that don't match the specified configurations. Doing that eliminated about a 60s build time penalty when resources are changed on every developer build.

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…