为什么我有几个"Player"的实例?

3
我正在开发一个具有音乐播放器功能的安卓应用。目前一切都正常运作,但我对自己的实现方式并不满意,所以我来这里寻求帮助。
这个应用是100%使用Kotlin和Compose编写的。我在可组合屏幕之间使用NavHost进行导航。这是一个非常糟糕的图示,展示了我感兴趣的部分 主活动包含NavHost。 NavHost包含所有的导航和可组合屏幕。
每个屏幕(不是每一个,但大多数)我都使用了一个PlayerScaffold,它接收一个顶部工具栏和内容,并正常地组合屏幕,但添加和更新了一个底部迷你播放器(类似Spotify)和一个可以向上滑动的全屏模态播放器。
每个内容屏幕都有自己的ViewModel,而迷你播放器和全屏播放器则有一个PlayerViewModel。
PlayerViewModel接收一个"Player"的实例,它是一个持有ExoPlayer实例并执行所有播放操作的类。
Player类由Dagger Hilt实例化,并在一个模块中定义。
@Module
@InstallIn(SingletonComponent::class)
abstract class PlayerModule {

    @Binds
    abstract fun bindPlayer(
        playerImpl: PlayerImpl,
    ): Player
}

此外,我还有一个前台服务“PlayerService”,用于在应用程序转到后台时保存“Player”实例,以便它可以保持对播放器的引用,避免被销毁。
我遇到的问题(现在已解决)是多个PlayerViewModel和Player实例被创建,因此如果我在一个屏幕上开始播放一首歌曲,然后切换到下一个屏幕,下一个屏幕上的播放器不会正确更新。我通过在Application类中持有PlayerViewModel的实例来解决这个问题,这样只会创建一个实例,但我对这种方法非常不确定。
我预期的工作方式是每个Compose屏幕都有一个PlayerViewModel的实例,但Player的实例对于所有ViewModel都是相同的。
如果Player类被注释为“Singleton”,为什么会有多个实例呢?
1个回答

1
我找到了答案,问题出在PlayerModule类中,我将其注释为
@InstallIn(SingletonComponent::class)

而我没有阅读文档,错误地认为这意味着它会自动将该模块中的所有内容都变成“单例”。

在函数中添加@Singleton解决了这个问题。不需要在任何地方保留viewmodel的实例,现在它按预期工作。

@Module
@InstallIn(SingletonComponent::class)
abstract class PlayerModule {

    @Singleton
    @Binds
    abstract fun bindPlayer(
        playerImpl: PlayerImpl,
    ): Player
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接