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

fdx2calv  于 2023-03-24  发布在  Kotlin
关注(0)|答案(1)|浏览(148)

我有一个工作应用程序,它使用Room数据库来维护一个体育联盟名册,使用一个回收器适配器和一个RosterViewModel类和Factory。几个片段每个示例化一个视图模型来访问数据库。名册数据库有一个表,每个球员的记录。

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

在viewModel中:

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(在应用程序处于活动状态时跟踪两支球队之间的比赛)。为了在match db中填充球员记录,我需要访问roster db。match db有两个表。球员记录与roster db中的记录不同。
在(新的)匹配片段中定义两个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 Factory:

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*

显然这两个示例化并不是完全独立的,但我不明白为什么。如果RAM可用的话,视图模型代码片段来自Android Developers Codelabs(已经一年多了)。
我已经尝试了各种各样的ViewModel定义的排列,但都没有成功。我发现的另一个关于一个片段中两个视图模型的SO问题并不适用。许多ViewModel教程都没有帮助。
这是一个未发布的单用户应用程序,有一个小的数据库(〈300条记录),所以如果需要的话,我愿意在主线程中访问数据库。

ncgqoxb0

ncgqoxb01#

你似乎试图使用 * 两个 * 应用程序类,但Android应用程序正好有 * 一个 *。
最简单的做法可能是将两个数据库放在一个应用程序类中。

class SingleApplication : Application() {
    val playerDatabase : PlayerDatabase by lazy { PlayerDatabase.getDatabase(this) }
    val matchDatabase : TeamsDatabase by lazy { TeamsDatabase.getMatchDb(this) }
}

相关问题