将有状态的存储库注入WorkManager Worker

问题描述 投票:0回答:1

这主要是一个应用架构问题。我有一个存储库类,用于集中对媒体集合进行操作:

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)?如何更改我的应用程序体系结构以避免泄漏?

我的想法

  1. 使ContentObserver为无状态,并将媒体列表公开为MediaRepository。然后,消费者有责任缓存最新值。
  2. 将缓存保留在Flow中,但不要在服务和辅助服务器之间共享实例。
  3. 根本不使用缓存,因为大多数数据都是从设备的存储中读取的。
android dagger-2 kotlin-coroutines android-workmanager
1个回答
0
投票

我想您已经声明了一个匕首组件。

您仅使用@Singleton标记提供的MediaRepository实现。

MediaRepository

并且在模块中将此实例绑定到其接口

@Singleton
class MediaRepositoryImpl @Inject constructor(...)

要为Worker提供其他参数,您必须在应用程序中实例化自定义WorkManagerFactory。

@Binds fun bindsMediaRepository(impl: MediaRepositoryImpl): MediaRepository 逐步详细解释了整个过程。

也看一下This medium post

© www.soinside.com 2019 - 2024. All rights reserved.