如何在一个片段中为两个数据库实例化两个 ViewModel

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

我有一个工作应用程序,它使用 Room 数据库来维护体育联盟名册,带有回收器适配器和单个 RosterViewModel 类和工厂。几个片段各自实例化一个视图模型以访问数据库。 roster db 有一张表,每个玩家一条记录。

In each fragment:
    private val viewModel : RosterViewModel by activityViewModels {
        RosterViewModelFactory(
                (activity?.application as RosterDbApplication).myDatabase.itemDao()
        )
    }

在视图模型中:

class RosterViewModelFactory(private val itemDao : DbDao) : ViewModelProvider.Factory {
    
    override fun <T : ViewModel> create(modelClass : Class<T>) : T {
        if (modelClass.isAssignableFrom(RosterViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return RosterViewModel(itemDao) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }

现在我要添加另一个片段以使用 inMemoryDatabase(在应用程序处于活动状态时跟踪 2 个团队之间的比赛)。要在比赛数据库中填充球员记录,我需要访问花名册数据库。匹配数据库有两个表。球员记录与名单数据库中的不一样。

在(新)匹配片段中定义两个 ViewModel:

val leagueViewModel : RosterViewModel by activityViewModels { RosterViewModelFactory(
            (activity?.application as RosterDbApplication).myDatabase.itemDao())
        }
val matchViewModel : MatchViewModel by activityViewModels() {MatchViewModelFactory(
        (activity?.application as MatchDbApplication).matchDatabase.matchDao())
        }

(新)matchViewModel 工厂:

class MatchViewModelFactory(private val matchDao : MatchDao) : ViewModelProvider.Factory {
   
   override fun <T : ViewModel> create(modelClass : Class<T>) : T {
      if (modelClass.isAssignableFrom(MatchViewModel::class.java)) {
         @Suppress("UNCHECKED_CAST")
         return MatchViewModel(matchDao) as T
      }
      throw IllegalArgumentException("Unknown ViewModel class")
   }

应用类:

class RosterDbApplication : Application() {
    val myDatabase : PlayerDatabase by lazy { PlayerDatabase.getDatabase(this) }
}

class MatchDbApplication : Application() {
    val matchDatabase : TeamsDatabase by lazy { TeamsDatabase.getMatchDb(this) }
}

我实例化的两个视图模型中的任何一个首先起作用。但是第二个总是抛出一个致命的异常。当 matchViewModel 是第一个时,我得到这个:

*RosterDbApplication cannot be cast to MatchDbApplication*

当 rosterViewModel 是第一个时,我得到相反的结果:

   *MatchDbApplication cannot be cast to RosterDbApplication*  

显然这两个实例化不是完全独立的,但我不明白为什么。 viewmodel 代码片段来自 Android Developers Codelabs,如果 RAM 可用(已经一年多了)。

我已经尝试了 ViewModel 定义的各种排列但没有成功。我在一个片段中发现的关于两个视图模型的另一个 SO 问题不适用。许多 ViewModel 教程都没有帮助。

还有另一种构建视图模型的方法吗?这是一个单用户未发布的应用程序,有一个小的(<300 records) db, so I'd be willing to access the db in the main thread if necessary.

android kotlin android-room viewmodel
1个回答
0
投票

你似乎在尝试使用 two 应用程序类,但 Android 应用程序恰好有 one.

最简单的事情可能是将两个数据库放在一个应用程序类中。

class SingleApplication : Application() {
    val playerDatabase : PlayerDatabase by lazy { PlayerDatabase.getDatabase(this) }
    val matchDatabase : TeamsDatabase by lazy { TeamsDatabase.getMatchDb(this) }
}
© www.soinside.com 2019 - 2024. All rights reserved.