When building Android applications with Jetpack ViewModels, proper resource management is crucial to prevent memory leaks and ensure efficient cleanup of services. In this post, we’ll explore an elegant pattern that leverages Kotlin’s AutoCloseable interface to clean up resources when a ViewModel is destroyed automatically.
The Problem
Traditionally, when a ViewModel needs to clean up resources, we override the onCleared()
method:
class MyViewModel(private val itemsService: ItemsService) : ViewModel() {
override fun onCleared() {
super.onCleared()
itemsService.cleanup()
}
}
While this works, it requires boilerplate code for each service that needs cleanup.
AutoCloseable Pattern
Android’s ViewModel
class supports automatic resource cleanup through the AutoCloseable
interface. When a ViewModel is cleared, any services that implement AutoCloseable
and are passed to the ViewModel constructor will automatically have their close()
method invoked.
Implementing AutoCloseable Services
First, make your service implement AutoCloseable
:
interface ItemsService : AutoCloseable {
val items: Flow<List<Item>>
suspend fun getItems(): List<Item>
// ... other methods
}
Then implement the close()
method:
class RealItemsService : ItemsService {
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
[....]
override fun close() {
scope.cancel()
println("ItemsService closed - resources cleaned up")
}
}
Passing AutoCloseable Services to a ViewModel
Here’s the key: you can directly pass all your AutoCloseable
services to the ViewModel
constructor, and let the framework handle cleanup automatically.
class HomeViewModel(
private val itemsService: ItemsService,
private val customersService: CustomersService,
private val invoiceService: InvoiceService
) : ViewModel(
itemsService,
customersService,
invoiceService
) {
[....]
}
When HomeViewModel
is cleared, the Android framework automatically calls close()
on each of these services — no need to override onCleared()
or introduce a custom BaseViewModel
.
Conclusion
The AutoCloseable
pattern in ViewModels provides an elegant solution for automatic resource management. By implementing AutoCloseable
on your services and passing them to the ViewModel constructor, you ensure proper cleanup without writing repetitive boilerplate code. This approach leads to cleaner, more maintainable code while preventing memory leaks and ensuring resources are released appropriately.
Happy coding!
Top comments (0)