Back to Projects
🎵

ExoPlayer-Android-MVVM

ExoPlayer-Android-MVVM is a performance-oriented Android music player demonstrating modern Android development standards. It leverages Jetpack Compose for a fully reactive UI, Clean Architecture for a decoupled codebase, and Media3 ExoPlayer for rock-solid background playback. The app handles large music libraries with Paging 3 and uses Kotlin Flow operators for resource-efficient search.

Tech Stack

KotlinJetpack ComposeMedia3 ExoPlayerPaging 3HiltKotlin FlowRetrofitOkHttp

The Problem

Building a music player that handles large libraries while maintaining smooth 60fps UI performance and uninterrupted background playback was the core challenge.

The Solution

Decoupled playback into a Foreground Service using Media3 ExoPlayer, completely isolated from the UI lifecycle. Combined Paging 3 for efficient data loading with Kotlin Flow operators to make search reactive and resource-efficient.

Architecture

Follows Clean Architecture with three layers: Presentation (Compose + ViewModel), Domain (Use Cases), and Data (Repository + Retrofit + Paging). The playback engine runs as a Foreground Service decoupled from the UI layer.

Key Features

  • Media3 ExoPlayer with Foreground Service for uninterrupted background playback
  • Paging 3 for efficient large dataset handling in song & search screens
  • Kotlin Flow with debounce & distinctUntilChanged for resource-efficient search
  • Custom OkHttp Interceptor with centralized error handling & ConnectivityObserver
  • MVVM + Clean Architecture with strict separation of concerns

Engineering Challenges

  • Synchronizing Paging 3 state with ExoPlayer queue without memory leaks
  • Handling audio focus changes and system interruptions gracefully
  • Building efficient search with Flow operators to avoid unnecessary API calls

Lessons Learned

  • 💡Media3 ExoPlayer is vastly superior to the legacy API for building robust music apps
  • 💡Centralizing network error handling in an OkHttp Interceptor dramatically reduces boilerplate
  • 💡Paging 3 requires careful thought around invalidation and refresh strategies