♣️ 🅾️ 😳
🍒 👎 🐀
CLOCK FACE FIVE-THIRTY
CLUB SUIT O BUTTON FLUSHED FACE
CHERRIES THUMBS DOWN RAT
I made an absurd little thing that generates haikus from the official unicode emoji descriptions.
I came across the idea after seeing a bunch of bots on twitter recently – particularly @WizardGenerator and a few bots from @tinysubversions. After reading something that said that the best way to get started was to take a concept, boil it down to something as minimally viable as possible, and ship it, I decided to have a go.
I thought it was funny to juxtapose something ancient, and old, and introspective, and personal, and effort-requiring against something modern, and ephemeral, and mass consumed.
Real haikus make you think; this is like the bastard limerick of haikus.
Also, I’ve always been interested in emoji (they feature on the homepage of my website). It’s utterly bizarre that something so modern has been somewhat standardised into language through the Unicode spec.
Emojis and meaning
Emoji illustrations have implicit meaning by virtue of being pictures, but a lot of the meaning now comes as a result of the fact that Apple mainstreamed emoji first. The dancing lady is classy and exuberant, but the Unicode spec just says “DANCER” (with the note also used for “let’s party”). It makes no mention of pose, gender, the red dress, or a particular dance style. Just “DANCER”. I’ve seen PERSON WITH FOLDED HANDS used as high-five. The Japanese INFORMATION DESK PERSON emoji is often used to mean sassy. People interpret the FACE WITH TEARS OF JOY emoji as just “crying” (with hilarious/disastrous results).
So for something that’s so ubiquitous, it’s amazing that nobody knows what these symbols formally mean. Maybe the problem here is that they were mobile-first for so long - you can’t include a formal description when the keyboard has to fit on a 4” screen. Maybe the entries in the unicode specification was under-specified. Maybe in seeking to make emoji memorable and fun, Apple engineers were a little too liberal in their interpretation of the spec.
Either way, we’re in a situation where emoji have a richness and layers in meaning. Not to the same quality of words, but hey, at least they’re mainstream and accessible.
HEY THE SPEC IS IN ALL CAPS FOR SOME REASON
It’s also extremely entertaining to me that the UNICODE DESCRIPTIONS are always UPPERCASE. it’s like the spec is yelling at us: “HEY, YOU! that’s a DOG FACE.” “DEAR READER! This is a MAN IN BUSINESS SUIT LEVITATING.”
So juxtaposing something ancient, and nuanced, and subtle, against something modern, and really really blunt and TIRELESSLY YELLING really appealed to me.
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’ 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.
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.
Run the following commands in a terminal. These values are for a Sony Xperia Z2 tablet, but you can substitute them for other values:
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:
That’s it! Feel free to drop me a note and let me know if this works on your device.
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/>):
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.
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.
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.
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.
…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:
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.
Our metrics look like hockey sticks and we just closed a Series A for $20m, probably. Our logo is the pair of emoji 📷🚀. ↩
An alternative to the BadApp#getInstance() method is to use (BadApp) context.getApplicationContext(). This isn’t any better. ↩
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. ↩