The Challenge
When you make changes to your code, Compose Hot Reload:- Reloads the changed classes
- Migrates the heap to the new class definitions
- Re-initializes static fields (when necessary)
- Invalidates and re-renders affected Compose code
What is Global State?
Global state includes:- Singleton objects
- ViewModels that persist across recompositions
- Caches stored in companion objects
- Service instances
- Databases and repositories
- Any data that outlives individual Composable instances
Solutions
When changes to global state cause issues, you have two options:Option 1: Restart the Application
The simplest solution is to restart your application after making changes that affect global state. This ensures a clean slate.Option 2: Reset State Using Runtime API Hooks
For a better development experience, you can manually reset global state using the Compose Hot Reload Runtime API.Using the Runtime API
First, add the runtime API dependency:build.gradle.kts
Non-Composable Option: staticHotReloadScope
UsestaticHotReloadScope.invokeAfterHotReload() to register cleanup hooks outside of Composable functions:
Composable Option: AfterHotReloadEffect
UseAfterHotReloadEffect within Composable functions for automatic lifecycle management:
ViewModel Support
One of the most common examples of global state isViewModel classes from Android’s Architecture Components or similar libraries. ViewModels persist their state through UI changes, which means any data they store will be retained after hot reload.
The Problem
When you change a data class that’s referenced by a ViewModel:UiData instance with label = "Hello". This can cause:
- UI not reflecting code changes
ClassCastExceptionerrors- Unexpected behavior
Solution: Reset ViewModels After Hot Reload
Composable Approach
Reset ViewModels within your Composable code:Non-Composable Approach
For more control, usestaticHotReloadScope:
Complete Example
Here’s a full example showing how to handle ViewModels with hot reload:Best Practices
1. Use isHotReloadActive Guards
Always guard hot reload-specific code to prevent it from running in production:2. Prefer AfterHotReloadEffect in Composables
When working within Composable functions, useAfterHotReloadEffect instead of staticHotReloadScope for automatic cleanup: