This is mostly an app architecture question. I have a repository class that centralizes operations on collections of media:
interface MediaRepository {
suspend fun getTracks(): List<Track>
suspend fun getAlbums(): List<Album>
fun observeMediaChanges(): Flow<ChangeNotification>
}
This repository pulls from multiple DAOs sources that expose their data as Flow
to observe for changes like the following:
interface MediaDao {
fun getTracks(): Flow<List<Track>>
fun getAlbums(): Flow<List<Album>>
}
Therefore, the implementation of MediaRepository
is stateful: it lazily observes changes to the Flow
s from the first time the equivalent getX
function is called, caches the latest received value whenever received then compute and broadcasts a ChangeNotification
to observers of observeMediaChanges()
.
This structure worked well when the Repository
was only injected into a Service
, because the repository resources could be cleaned-up when the service terminated. I now need to inject the same MediaRepository
into an instance of Worker
. Since workers have their own lifecycle, I need to make the MediaRepository
a singleton.
The problem
by keeping active subscriptions for the whole lifetime of the application, am I leaking valuable resources (for example, one DAO internally uses ContentObserver
s) ?
How can I change my app architecture to avoid leaks ?
What I thought of
- Make
MediaRepository
stateless and expose media lists asFlow
s. It is then the consumer's reponsibility to cache the latest value. - Keep the cache in
MediaRepository
, but do not share instances between the service and the worker. - Do not use a cache at all, since most data are read from the device's storage.