这主要是一个应用架构问题。我有一个存储库类,用于集中对媒体集合进行操作:
interface MediaRepository {
suspend fun getTracks(): List<Track>
suspend fun getAlbums(): List<Album>
fun observeMediaChanges(): Flow<ChangeNotification>
}
此存储库从多个DAO源中提取数据,这些源将其数据公开为Flow
,以观察是否有如下变化:
interface MediaDao {
fun getTracks(): Flow<List<Track>>
fun getAlbums(): Flow<List<Album>>
}
因此,MediaRepository
的实现是有状态的:它从第一次调用等效的Flow
函数起就懒于观察getX
的变化,每当接收到最新的接收值时就对其进行缓存,然后计算并广播[C0 ]给ChangeNotification
的观察者。
当仅将observeMediaChanges()
注入到Repository
中时,此结构运行良好,因为可以在服务终止时清理存储库资源。现在,我需要将相同的Service
注入到MediaRepository
的实例中。由于工作人员有自己的生命周期,因此我需要将Worker
设为单例。
通过在应用程序的整个生命周期中保持活动订阅,我是否泄漏了宝贵的资源(例如,一个DAO在内部使用MediaRepository
)?如何更改我的应用程序体系结构以避免泄漏?
ContentObserver
为无状态,并将媒体列表公开为MediaRepository
。然后,消费者有责任缓存最新值。Flow
中,但不要在服务和辅助服务器之间共享实例。我想您已经声明了一个匕首组件。
您仅使用@Singleton标记提供的MediaRepository实现。
MediaRepository
并且在模块中将此实例绑定到其接口
@Singleton
class MediaRepositoryImpl @Inject constructor(...)
要为Worker提供其他参数,您必须在应用程序中实例化自定义WorkManagerFactory。
@Binds fun bindsMediaRepository(impl: MediaRepositoryImpl): MediaRepository
逐步详细解释了整个过程。
也看一下This medium post