HBO (WarnerMedia)
HBO GO Android — Architecture Modernisation & Performance
Led architecture modernisation and Kotlin migration for HBO GO's Android app, serving 10M+ users across Central and Eastern Europe. Reduced crash rate by 40%, improved UI smoothness from 45 to 58 fps average, and cut build times by 35%.
- 40%
- Crash rate reduction
- 45 → 58 fps
- UI frame rate improvement
- 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:
- 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:
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 |
|---|---|---|
| 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 app maintained 4.3★ on the Play Store throughout the modernisation. 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.