The emulator is not Android. Real devices are.
Android's difficulty is not the language. It is manufacturer firmware, background execution limits, memory on a mid-range phone and a fleet of OS versions, none of which the emulator shows you.
- Language
- Kotlin, with Java where it survives
- UI
- Jetpack Compose and Views, usually mixed
- Tested on
- Real devices, not just emulators
- Engagement
- Monthly rolling, 30 days notice
- Interview
- You meet them, you can decline
- Overlap
- 4–6 hours with US and EU
The language is the easy part.
Kotlin is a pleasure and Compose has genuinely improved how Android UI is built. Neither addresses what makes Android engagements overrun, which is the gap between a device on your desk and the fleet your users are holding.
Background execution is the clearest example. Doze, app standby, and per-manufacturer battery optimisations mean scheduled work that runs reliably on a Pixel may not run at all on some popular devices. An engineer who has not met this will architect around an assumption that does not hold.
Memory is the second. A mid-range device with several applications open behaves very differently from a development phone, and image-heavy screens are where it shows first.
Then permissions, which have changed materially across recent releases, and storage access, which has changed more than once. An engineer whose Android knowledge is a few versions old will write code that works on their device and fails a review or a user.
Four things that decide the difficulty.
None of these are visible from a feature list, and all of them change the estimate.
| Factor | Why it matters | What we ask |
|---|---|---|
| Minimum OS version | Every version back adds compatibility work | What does your analytics show? |
| Device mix | Manufacturer firmware differs in ways documentation does not cover | Which devices are the top ten in your base? |
| Background work | Doze and battery optimisation vary by manufacturer | Does anything need to run when the app is closed? |
| Compose or Views | Most real codebases are both | What is the existing code, honestly? |
| Play Store policy | Target API requirements arrive on a schedule | When did you last update the target SDK? |
What we ask an Android engineer.
Chosen to find out whether somebody has shipped to a real user base or only to a development device.
What is on Play under your name?
Live links, and ideally something with a real install base. Shipping is the skill.
What have you had to fix for one manufacturer?
Everyone who has shipped at scale has a story. Nobody who has only used the emulator does.
How do you run work in the background reliably?
WorkManager, foreground services, and an awareness that reliability varies by device. The most common architecture mistake on Android.
Compose or Views, in an existing codebase?
Interoperability, and judgement about where to draw the line. Answers advocating a full rewrite are a warning sign.
How do you diagnose a memory problem?
Profiler, leak detection, bitmap handling. Image-heavy screens on mid-range devices are where Android apps fall over.
How do you handle a runtime permission being denied twice?
Tests whether they have shipped against recent permission behaviour rather than remembering how it used to work.
A device matrix costs less than one wasted sprint.
This is the single cheapest quality intervention available on an Android project and it is the one most often left out of a budget.
- Your users' top ten devices, from analytics. Not a guess and not the team's phones. The list is usually surprising and it is the only one that matters.
- At least one low-memory mid-range device. Where memory and performance problems appear first, and where a large share of any real user base sits.
- At least two manufacturers. Firmware differences in background execution, notifications and permissions are real and not documented anywhere useful.
- The oldest OS version you support. Whatever your analytics says, not whatever is convenient. Supporting it and never testing it is the worst of both.
- A cloud device farm for the long tail. Cheaper than owning hardware for the cases you hit twice a year.
- Pre-launch reports from the Play Console. Free, automated on real hardware, and routinely ignored.
Rates, notice and how we interview, on one page.
The commercial mechanics are the same whichever role you are hiring, so they live in one place, not being restated on every page.
Hiring Android engineers.
Three that most affect the estimate.
Why do Android estimates run over more than iOS?
Fragmentation, almost every time, and it is systematic, not bad luck. On iOS there is a small, well-documented set of devices and OS versions, and behaviour is consistent across them. On Android the same code meets many manufacturers' firmware, several OS generations and a wide range of memory and performance profiles, and the differences that matter (particularly around background execution, notifications and battery optimisation) are not documented in any single place. The mitigation is not a bigger contingency, it is testing on real devices from the first sprint rather than the last, so the surprises arrive when there is still time to design around them.
Kotlin or Java?
Kotlin, without much hesitation. It is the default for Android, the tooling and documentation assume it, Compose is Kotlin-first, and the ergonomics around null safety and concurrency remove entire categories of the crashes that used to dominate Android bug reports. Java interoperates fully, so an existing Java codebase does not need converting, new code can be Kotlin alongside it, which is how we would approach an inherited application. What we would not do is a wholesale conversion as a project in its own right; it produces a large diff, a regression risk and no user-visible benefit.
Compose or Views?
Compose for new screens, Views where they already exist and work. The interoperability is good in both directions, so a mixed codebase is a normal and supportable state rather than a transitional embarrassment, and most production Android applications are exactly that. Be wary of an engineer who wants to convert everything: it is a large amount of work, it carries real regression risk on screens that currently function, and the user sees nothing. The exception is a screen being substantially reworked anyway, where rebuilding it in Compose costs little more than the rework.
