Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android fragments “最好的方法”;刷新“;由Room数据库提供的LiveData_Android Fragments_Kotlin_Android Room_Android Lifecycle_Kotlin Coroutines - Fatal编程技术网

Android fragments “最好的方法”;刷新“;由Room数据库提供的LiveData

Android fragments “最好的方法”;刷新“;由Room数据库提供的LiveData,android-fragments,kotlin,android-room,android-lifecycle,kotlin-coroutines,Android Fragments,Kotlin,Android Room,Android Lifecycle,Kotlin Coroutines,我目前正在使用Room存储单词翻译列表,并将查询作为LiveData返回以监视插入和更新。然而,当我需要重新获取不同源语言的翻译时,我遇到了问题(我当前的策略是将livedata重新分配给room查询的结果) 我使用下面的SQL查询获取要翻译的语言和特定语言的翻译 @Dao interface TranslationDatabaseDao { ... //Returns all pairs of languages to translate to/from @Query("S

我目前正在使用Room存储单词翻译列表,并将查询作为LiveData返回以监视插入和更新。然而,当我需要重新获取不同源语言的翻译时,我遇到了问题(我当前的策略是将livedata重新分配给room查询的结果)

我使用下面的SQL查询获取要翻译的语言和特定语言的翻译

@Dao
interface TranslationDatabaseDao {
   ...

   //Returns all pairs of languages to translate to/from
   @Query("SELECT * FROM language_pairs")
   fun getAllLanguagePairs(): LiveData<List<LanguagePair>>

   //Returns translations with the specified source language
   @Query("SELECT * FROM translations WHERE sourceLanguage = :language")
   fun getTranslations(language: String): LiveData<List<TranslationResult>>

   ...
}
重新分配翻译列表会导致观察livedata的片段继续观察旧的livedata,因此我的策略是在更改语言时删除观察者并在片段中重新分配它。这似乎不是最好的解决方案,我也不知道如何确保在删除前一个观察者并重新创建它之前加载了数据(我正在使用协同路由,因此我需要一种在返回livedata时进行回调的方法)

可能的解决方案
  • 让数据库只返回一个列表对象,而不是livedata。然后我可以将其存储在可变的livedata中。这并不理想,因为插入和更新不会自动反映在返回的列表中,所以每次更改特定语言的翻译列表时,我都必须重新获取数据
  • 获取所有翻译,然后在每次语言更改时对其进行筛选。一旦语言列表变大,这将有点资源密集

  • 所以我的问题是:有没有更好的方法在语言更改后重新分配livedata?或者更确切地说,是否有一种可接受的方式让片段意识到这种重新分配?

    您可以为该语言再创建一个
    LiveData
    ,并使用它将其映射到翻译,如:

    class translationViewmodel(private val database: TranslationDatabaseDao, initLanguage: String): ViewModel() {
      val language = MutableLiveData<String>("en")
      val translations = language.switchMap { language -> 
        database.getTranslations(language)
      }
      ...
    }
    

    谢谢,这真是太棒了!我以前认为这是不可能的,因为数据库调用应该封装在协同程序启动块中。@JJJacobs不客气。返回
    LiveData
    的Dao方法已经在后台线程中获取它,所以从后台线程调用它们是没有意义的。
    class translationViewmodel(private val database: TranslationDatabaseDao, initLanguage: String): ViewModel() {
      val language = MutableLiveData<String>("en")
      val translations = language.switchMap { language -> 
        database.getTranslations(language)
      }
      ...
    }
    
    viewmodel.language.value = "es"