Three tips for better Android development productivity

I’ve been working on Android apps at Google for about two years. In that time I’ve worked on a diverse set of codebases - from small, tightly-contained internal tools that only target Lollipop and newer, to extremely complicated apps with large development teams, such as Google Maps, and even system-level code such as the Activity Manager for Android Auto. In that time, I’ve also seen a lot of new team members come up to speed, and found myself consistently giving the same advice to help them get there quickly. Here’s my top three tips for becoming productive whilst developing for Android.

1. Learn how to navigate through code in your IDE

Rule number 1 of writing code is that you’ll spend more time reading code than actually writing it. If you’re using Android Studio (it’s pretty good!), you can make this easier by learning how to navigate through code semantically. Basically, take a look at the Navigate menu and make yourself familiar with the options there. My most commonly used options:

  • Go to Definition
  • Find superclasses / Find subclasses
  • Show call hierarchy

This advice was something my manager gave me when I first started programming Android, and it’s been the single biggest thing that improved my productivity developing for the platform. You’ll find yourself using these a lot, so it’s worth remapping them to keystrokes that work for you as well.

2. Read the source

Android’s frameworks aren’t always well-documented, but the most complete kind of documentation is source code, and the source code is available. Make sure you download the framework source as part of the Android SDK, and then when you use the code navigation features in Android Studio, you can jump right into the Android source and see what’s happening under the hood. You can install the Android source by checking the Sources box in the SDK manager. From the Android Studio menu, choose Tools –> SDK Manager –> Show Package Details, and then check the Sources option:

The SDK Manager in Android Studio

The ‘SDK Manager’ window.

3. Take the time to really understand lifecycle well

Android lifecycle is one of the most confusing paradigms I’ve ever worked with in programming. Unfortunately, it’s also crucial to the platform, so it’s important to make sure you understand it well so you don’t introduce subtle bugs.

As an example, I’ve seen lots of code that resumes and pauses rendering in onResume() and onPause() respectively. These callbacks don’t indicate visibility, though, they indicate that the Activity is in the foreground, and that the user can interact with the app. This results in a problem where rendering stops when a dialog pops up over the top, for example. Instead, rendering should be started and stopped in onStart() and onStop(), respectively, which indicate when the Activity is visible at all.

The best guide to Android lifecycle is in the Android documentation for the Activity class.

That’s it!

Hopefully these three tips will help you to get up and running quicker with Android development! Let me know if you’ve got any other advice that really helped you to get started.


Faking Screen Resolution on Android Devices

Required hardware and an open-source project

For the Buendia medical records system project, we’re building an Android tablet app that’s capable of displaying and modifying electronic records out in the field. So far, we’ve been targeting the Sony Xperia Z2 tablets as our reference platform - they’re a great size, they’re really light and they’re waterproof.

The project is open-source, and we’re finding that we have contributors who want to help, but don’t have a tablet device to test on. We’ve had developers use the Android emulator before, but emulation can be quite resource-intensive. Even if you’ve enabled HAXM (it’s a huge speed-up if your processor supports it!), the emulator still uses a couple of GB of RAM, which, in combination with Android Studio, can push even modern hardware pretty hard!

Whilst not everyone has an Android tablet, lots of our developers have Android phones, and want to use them for running the app, even though we’re not planning on supporting phones currently. It turns out you can tell Android’s Window Manager to use whatever resolution you want, and using this, we’re able to help developers be just a little more productive without the Android tablet.

Faking the resolution

Here’s how to do it:

  1. Make sure you have the Android SDK or Android Studio setup, and you can connect to your Android device using USB Debugging Mode.
  2. Run the following commands in a terminal. These values are for a Sony Xperia Z2 tablet, but you can substitute them for other values:
$ adb shell wm size 1920x1200
$ adb shell wm density 240
$ adb reboot

A few notes:

  • It’s important to reboot after you’ve changed the density. Most apps don’t know how to deal with changes in density, and so most images and layouts will have bits that are too big or too small unless you reboot.
  • You might need to swap the 1920x1200 for 1200x1920 depending on the default orientation of your device.
  • This setting persists until you change it back explicitly; you might want to bookmark this page ;)
  • I tested this on a Nexus 5 running Lollipop; it might not work on older versions of Android.

Setting it back

These settings will persist until you reset them manually, so make sure to run this when you’re done and want your phone back to normal:

$ adb shell wm size reset
$ adb shell wm density reset
$ adb reboot

That’s it! Feel free to drop me a note and let me know if this works on your device.


App-level Resources Done Right on Android

Lots of developers love the Application class as a container for application-wide resources, because:

  • it’s a singleton, so it’s easy to ensure that each of these global resources is only initialized once
  • it has access to a Context (in fact, it is a Context), and
  • it’s easy to obtain a reference to the Application from anywhere.

This, however, is actually a really bad idea that will only cause you pain, for two main reasons:

  • It creates memory pressure on the rest of the operating system when your app is invoked for simple tasks, and
  • It gives Application too much scope, which makes your code harder to maintain.

I’m going to explain these reasons in detail, but first, I’ll show you how not to do app-level state, using an example app that I just made up. It’s called PictoBlaster, because it allows you to apply filters to pictures and then ‘blast’ them to your friends1.

How not to do it

It’s really easy to go down the route of putting resources in your Application class (again, please don’t do this):

  • Write a BadApp class that inherits from the Application class
  • In your AndroidManifest.xml, add the android:name attribute to your application (in the same way that you would for an <activity/> or <service/>):
<application
  android:name="com.example.pictoblaster.BadApp" >
  <!-- ... -->
</application>
  • In your BadApp.java2:
public class BadApp extends Application {
  private static BadApp sInstance;

  @Override
  public void onCreate() {
    // TODO: Initialize app-wide resources
    sInstance = this;
  }

  public static BadApp getInstance() {
    return sInstance;
  }
}

Seriously, don’t do this.

Why not?

1. Memory Pressure

Developers often forget that BadApp is loaded into memory when Android initializes your process, and before any other component can be loaded. That’s not a big problem for apps that only have a single Activity, but as soon as you start adding other components (other Activities, Services, BroadcastReceivers, or ContentProviders), BadApp has to load all its dependencies before any of those can be started. This is especially true for components that are supposed to be lightweight, such as BroadcastReceivers and ContentProviders.

Loading those resources burdens the operating system unnecessarily. Consider the following scenario:

  • A user decides they want to send a picture from PictoBlaster to a friend, so they press the “Send” button in the app.
  • PictoBlaster detects that it’s not connected to the network, so it queues up the message for when it receives an android.net.conn.CONNECTIVITY_CHANGE broadcast.
  • The user opens up another app, and PictoBlaster’s process gets killed because PictoBlaster is not in use any more.

So far, so good. The problem occurs when the PictoBlaster process has to be loaded again for what should be a lightweight component:

  • The user’s phone detects a network connection change, and notifies PictorBlaster’s BroadcastReceiver.
  • Because the PictoBlaster process died earlier, it has to be recreated, which means that the BadApp class loads all of its resources into memory – Filters, Cheesy memory-intensive stickers, Fonts, everything.
  • After BadApp has finished initializing, the BroadcastReceiver finally loads.
  • The BroadcastReceiver notices that the phone has reconnected, reads the file from disk, sends it over the network, and exits.
  • The system then detects that PictoBlaster is no longer in use, and frees up all the memory again.

Not only is this a waste of the users’ battery (how long did it take to initialize all that stuff?), if BadApp initializes enough stuff, it can also create memory pressure that causes other apps to be shut down3. This is especially true if the user’s loaded another memory-intensive app in the meantime.

Yikes.

The root problem: eager initialization

The root problem here is that resources are loaded eagerly on process start, whether they’re going to get used or not. This is almost never something you want. In a resource-constrained mobile environment, it wastes battery and memory, which can kill other apps that the user may be interacting with. That’s a terrible user experience.

It is possible to work around this by making all of your Application-level resources lazy-loaded using an explicit lazy initialization mechanism, such as Guava’s Suppliers.memoize() or Apache Commons’ LazyInitializer. This workaround still doesn’t solve the maintainability problem, though.

2. Maintainability

The other major problem with initializing all your resources in your Application is that it makes it easy to give your Application too much scope. Once there’s a precedent for putting app-wide resources in your Application class, other developers on your team will put them there too. Then, you’ve got a class that owns loads of different resources.4

A side effect of giving your Application too much scope is that if you ever want to reuse code that uses these dependencies, pulling the code out into a separate library isn’t a simple task - you’ve got to decouple your app-wide resources from the Application object first.

A solution: the good old-fashioned static instance

I think that the real reason why a lot of developers like the Application class so much is that programmers have often been taught that static members are evil. Actually, static members are extremely useful whenever you’re working with resources that are scoped to a process (the app, in this case). The Application class represents exactly the same concept, it just allows developers to avoid the icky feeling they get from using static members instead.

Java’s semantics for static members are pretty useful. Static members are initialized when the class is loaded, which means that they’re loaded the first time you use a static member or instantiate the class. This gives you lazy-loading for free, without having to write boilerplate yourself. The ‘static instance’ approach is one that Android framework engineers have recommended in the past.

The idea is to define a class like this:

public class AppWideResource {
  public static final AppWideResource INSTANCE = new AppWideResource();
  private AppWideResource() {}  
  // Rest of class implementation goes here...
}

…and then reference AppWideResource.INSTANCE whenever you need one.

There are a couple of disadvantages to this approach:

  • In order to make code that uses the singleton testable, you need to be consistent about passing static instances around as constructor parameters, instead of referring to the static instance directly (this concept is known as Dependency Injection). To be clear, the hard part of this isn’t passing static instances as parameters, it’s the consistency bit. Consistency is especially difficult on large or distributed teams.
  • It’s more boilerplate when you need access to the application-level Context. The Android documentation for Application hints at a solution like this:
public class AppWideResource {
  private static AppWideResource sInstance = null;
  private AppWideResource(Context context) {}

  // Synchronize this method to prevent the instance from being initialized
  // twice.
  public synchronized AppWideResource getInstance(Context context) {
    if (sInstance == null) {
      // Call getApplicationContext here because the original context might be
      // an Activity or Service, which won't be valid for the lifetime of the
      // static instance. An Application context will be valid for this entire
      // time.
      sInstance = new AppWideResource(context.getApplicationContext());
    }
    return sInstance;
  }
}

Likewise, if you need other static resources to initialize your AppWideResource, just add them as parameters to the AppWideResource#getInstance() method.

The structure of this approach means that:

  • Resources are lazy-loaded, which means your app won’t chew through a users’ memory or battery every time a ContentProvider or a BroadcastReceiver spins up
  • You’re establishing a pattern of making your app-wide resources isolated and distributed, which improves their modularity and reusability for the future.

  1. Our metrics look like hockey sticks and we just closed a Series A for $20m, probably. Our logo is the pair of emoji 📷🚀.

  2. An alternative to the BadApp#getInstance() method is to use (BadApp) context.getApplicationContext(). This isn’t any better.

  3. For more on how Android kills processes when memory is low, take a look at ‘Processes and Threads’.

  4. A really good indication that an object has too much scope is when you find yourself mocking things out in tests that seem completely unrelated. If you find yourself doing this, it might be time to rethink your design.


So I Rebuilt My Website

Domain names, social networks and online identity

This website has always been about having an identity on the internet. It was a vogue thing in the 2000s, I think. If you were SRS BSNS about the internet, you had your own domain name. And for some reason I took that and ran with it a few years late in 2011.

I maintain that personal websites occupy a unique space on the internet - it’s pretty much the only place where what you write isn’t massaged into a format for others to consume.

No seriously, let me unpack this a little. There’s two main axes that you can put categorize pretty much every social network into:

  • User control over their representation in the medium, and
  • Long-term vs short-term story-telling.

Personal websites are unique in that they can be whatever you want them to be, and as such they have a high level of user control over their representation. As a side-effect of this, it’s also easier to build something that tells a coherent story over a longer time-frame. Compare this to a few common social networks:

Facebook

On Facebook, The Feed is the core element, your identity on the service is almost entirely what you post to and what you interact with on The Feed. Virtually everything you interact with could be shown to your friends, even if it’s just clicking the little 👍 button. The profile exists only so that other users can ascertain who you are before adding you, and so that Facebook can target its ads better. You’ll notice that Facebook has reduced the role of the profile over the years as well - indicating “interests” was an important part of profile-building in the beginning, but that’s probably a hangup from being a competitor with MySpace a long time ago (You were not my friend, Tom). I’d argue that a notion of a profile is important for long-term story-telling, but Facebook are exploring more novel approaches in this area in the name of engagement.

Twitter

On Twitter, you’ve got the same core model, but the content is shallower, and you’ve got more control over what your followers see - everything that goes in your stream is there from a deliberate action, and if you ✭ something, that ✭ won’t be broadcast to all your friends (there were contentious attempts to change this recently). It’s even harder to tell a cohesive story over the long term on Twitter than it is on Facebook, because:

  • posts are somewhat temporal by the fact that there’s just so much other information on the network, and
  • the focus on speaking quickly isn’t conducive to the kind of quality that you really need for longevity.

Instagram

Instagram is an interesting one - the uniformity and non-text nature of the medium makes it easier to look back at old posts. It’s easier to tell a cohesive story over the long-term on Instagram, probably because Instagram profiles are reminiscent of photo albums. This isn’t the case for everyone, but I’ve certainly flicked back through my Instagram profile to find a photo for something that I was telling a friend about before. I’d wager it’s also because the content is first-user-generated - there’s no reshares on Instagram, so every single thing you post is something that you probably directly experienced.

A short history of capnfabs.net

Version 1

I put together Version 1 of this website whilst sitting in Engineering Management lectures at university, and it was inspired by Microsoft’s recent development of the Metro design language. It was, pure and simple, a blog, but I wrote the whole thing from scratch as a learning exercise, so it was AJAX-y, and had 300kB of Javascript, and Google Analytics, and Disqus for comments and <marquee>animations</marquee>, and the whole thing was powered by PHP and MySQL. I also had the insight that not everyone would be interested in all the different stuff that I was writing about, so I had this thing where you could filter categories, and the posts were all colour-coded. I was scratching at the idea of online identity, though, so I didn’t want to fork content into separate sites just because people might not be interested in all of it.

Version 1

Wow. At least it’s different, I guess?

Gosh Darn. What was I thinking? I think the laptop I was using then had terrible colour saturation. Also, I had to install Apache/PHP/MySQL and turn off a bunch of Deprecated MySQL-non-prepared-statement-API warnings to generate that screenshot. It brought back some bad memories (this is a good setup guide though).

Version 2

Version 2 was the same content, but converted to use Octopress 2, because the other site was kinda unusable, ugly and extremely difficult to maintain. It was also slow because it was stored in a MySQL database on a single server located in Melbourne, Australia (I think). It might’ve had a condition where the page rendering performance degraded the more articles you tried to load, too.

Anyway, now that I was using an entirely static site, I could move the whole thing over to Github pages, because I liked the idea of being hosted on a performant, worldwide CDN. This was mostly because of a desire to not be fireballed, because I had big hopes that something I wrote would one day be read by lots of people (lol). There was still a big focus on blogging and on content.

Version 2

Not as much personality; this was pretty close to the stock Octopress template.

Version 3

The Octopress blog was ok, but I found over the next few years whilst working full-time in a fairly demanding job that I didn’t really have time or energy to write. I found that I was returning to the idea of a domain as “an identity on the internet”, and was more interested in having a place to centralise content I’d produced elsewhere - on social media, particularly. So I started experimenting again late in 2014, and then rebuilt the site to the format you see today over the six months or so following.

Conceptually, what differs in this iteration compared to the last two is that it’s designed to stay relevant for minimal effort. I’ve done this by:

  • Using a static site for the homepage, and then only putting dynamically-updated content down the bottom.
  • Focussing on including content that I’m producing (or better yet, others are producing) from other parts of the web. I’m a heavy Instagram user, so Insta posts 📷 are included (yay!). I wrote the script / slides / choreography for a YouTube video for work, so that got included too.
  • Using a permalink mechanism that I appropriated from Daring Fireball. Those little unicode flags (⚑) next to article titles on the archive format page and the home page link to the commentary on this site; the article title links to the content origin. I went with the flags because they were part of an older unicode spec and so they’re more broadly implemented, I would’ve loved to use a Cactus 🌵 or a Taco but browser support isn’t quite as strong for these codepoints.1

Design-wise, I’ve updated for a bunch of newer web paradigms. So, it’s responsive (go ahead, take a look on your phone!), space / cache-efficient, and super clean. Drop shadows are subtle. There are no peeling stickers. Remember when that was a thing? That was the worst.

And that’s a brief history of the philosophy and design behind a very insignificant website. Take a peek at the code for v2 and v3 if you’re curious, or drop me a line if you’ve got any questions 😁


  1. Update (Jul 2016): As time went on, I found that the commentary I was writing was pretty important for interpretation of the work. This was particularly true for Embassy Reviews and Emoji Haikus, both of which are a little more abstract than content I’ve historically produced. To reflect the fact that I thought this commentary was important, and easy to miss with this design, I inverted the paradigm so that a ➤ (BLACK RIGHTWARDS ARROWHEAD) provides a direct link to the content, and the title is a link to the commentary.

← Older Index Newer →