HBO (WarnerMedia)
HBO GO Android — Architecture Modernisation & Performance
Hardened the UI layer of HBO GO's Android app for 10M+ users, cutting recurring UI defects from roughly 50% of weekly bug reports to about 5% and saving an estimated €100k/yr in engineering time, then modernised the architecture (Kotlin migration, MVVM + Hilt) and drove a 40% crash reduction.
50%
Before
5%
After
Share of weekly bug reports caused by UI issues
Robust, spec-driven UI components meant screens only changed when the spec changed, freeing the team to ship features instead of re-fixing the same layouts.
- 50% → 5%
- Recurring UI issues
- €100k/yr
- Engineering time saved
- 40%
- Crash rate reduction
- 35%
- Build time reduction
- 10M+
- Users
The Challenge
HBO GO’s Android app was built on a legacy Java codebase with a flat MVC architecture that had accumulated years of technical debt. As the streaming market became more competitive, the team needed to ship features faster — but the codebase was slowing everyone down.
Key problems:
- Fragile UI layer — recurring UI defects made up roughly half of every week’s bug reports. The same screens broke on almost every change, so the team spent more time re-fixing layouts than shipping features.
- High crash rate (~2.1%) degrading user experience in competitive streaming market
- UI jank on mid-range devices used by the majority of CEE users
- Long build times (40+ minutes for full build) slowing developer velocity
- No separation of concerns — business logic mixed with UI code, making testing nearly impossible
- Java codebase with no Kotlin, blocking adoption of modern Jetpack libraries
Approach
The engagement spanned 14 months and was structured in three phases, but the first measurable win came from hardening the UI layer.
Hardening the UI layer (the 50% → 5% result)
The single most expensive symptom was the UI: about half of every week’s bug reports traced back to the same fragile screens. Each layout change tended to break something adjacent, so engineers were re-fixing the same components instead of building new ones.
I re-architected those screens behind robust, spec-driven components: a single source of truth per screen, defensive handling of the edge cases that kept recurring (empty states, slow networks, partial JSON), and tests that pinned the behaviour. After that, a screen only changed when its specification changed, not because an unrelated edit had knocked it over.
The result: recurring UI defects fell from roughly 50% to about 5% of weekly bug reports. With UI issues no longer eating a large slice of the team’s week, the recovered engineering time was worth an estimated €100k/yr (conservatively, a meaningful fraction of several engineers’ time redirected from re-fixing layouts to shipping features). That freed-up capacity is what made the larger modernisation below affordable.
Phase 1 — Audit & Foundation (Months 1–2)
Started with a full technical audit: crash data from Firebase Crashlytics, frame timing from Android Profiler, and a codebase walk-through with the team.
Key findings:
- Memory leaks in the player component causing 30% of crashes
- UI thread blocking in network callbacks (pre-RxJava legacy code)
- Gradle build structure with no module separation causing full rebuilds
Delivered a prioritised action plan and got buy-in from engineering management for an 18-month modernisation roadmap.
Phase 2 — Kotlin Migration & Architecture (Months 3–10)
Ran Kotlin migration module-by-module, starting with the domain layer:
- Converted all data models, repositories, and use cases to idiomatic Kotlin
- Introduced MVVM with
ViewModel+StateFlowacross the entire app - Replaced RxJava with Kotlin Coroutines + Flow (gradual, no big-bang swap)
- Introduced Hilt for dependency injection, making the codebase testable
- Fixed all identified memory leaks — player component completely rewritten
Architecture decision: adopted Clean Architecture with three clear layers (data / domain / presentation) to give junior developers a predictable structure to work within.
Phase 3 — Performance & Build System (Months 11–14)
With the architecture stable, focused on measurable performance wins:
- Modularised the Gradle build into 12 feature modules — reduced incremental build time from 40 to 26 minutes
- Profiled UI rendering on target devices (mid-range Samsung and Xiaomi) — eliminated RecyclerView rebinds causing jank
- Replaced Glide with Coil (Kotlin-native, Coroutines-aware) for cleaner image loading
- Enabled R8 full mode and fixed all resulting issues — reduced APK size by 18%
Results
| Metric | Before | After |
|---|---|---|
| Recurring UI issues (share of weekly bug reports) | ~50% | ~5% |
| Engineering time saved | — | ~€100k/yr |
| Crash rate | 2.1% | 1.26% (−40%) |
| Average frame rate | 45 fps | 58 fps |
| Full build time | 40 min | 26 min (−35%) |
| APK size | 48 MB | 39 MB (−18%) |
| Unit test coverage | 4% | 31% |
The headline result is the UI-defect drop from ~50% to ~5% of weekly bug reports: it stopped the team from burning hours re-fixing the same screens and freed an estimated €100k/yr of engineering time for feature work. The app maintained 4.3★ on the Play Store throughout the modernisation, with zero production incidents caused by the migration.
What Made It Work
The key decision was to never stop shipping features during modernisation. Each module migration was done alongside feature work, not instead of it. The team saw immediate benefits — fewer crashes, faster tests, clearer code — which kept momentum high.
The other critical factor was documentation. Every new pattern was documented in the team wiki the day it was introduced. Junior developers could look up “how do we do X” and get an example from the actual codebase, not a Stack Overflow answer from 2018.
The architecture decisions here are the same ones I’d recommend for any new Android app today — see Android Architecture in 2025: Compose, MVVM, and Hilt for the post-Compose evolution of this stack. For a contrasting engagement shape — stepping into a live cross-platform program rather than a multi-month modernisation — see the Journey Rewards case study. And the engagement model itself is described under Android Development services.
Related service
Android Development services