Android 使用Transformations.map处理ViewModel中房间数据库中的LiveData

Android 使用Transformations.map处理ViewModel中房间数据库中的LiveData,android,kotlin,android-room,android-livedata,android-viewmodel,Android,Kotlin,Android Room,Android Livedata,Android Viewmodel,我有以下简单的数据库: NameList.kt @Entity(tableName = "name_list") data class NameList( @PrimaryKey(autoGenerate = true) var id: Long = 0L, @ColumnInfo(name = "name") var name: String = "") @Dao interface NameListDao{

我有以下简单的数据库:

NameList.kt

@Entity(tableName = "name_list")
data class NameList(
        @PrimaryKey(autoGenerate = true)
        var id: Long = 0L,

        @ColumnInfo(name = "name")
        var name: String = "")
@Dao
interface NameListDao{    
    @Insert
    fun insert(nameList: NameList)

    @Update
    fun update(nameList: NameList)

    @Query("SELECT * FROM name_list ORDER BY id DESC")
    fun getAll(): LiveData<List<NameList>>
}
class NameListRepository(private val nameListDao: NameListDao){
    val allNames: LiveData<List<NameList>> = nameListDao.getAll()
}
class MyViewModel(app: Application): AndroidViewModel(app){
    private val nameListDao = NameListDatabase.getInstance(app).nameListDao
    private val repository: nameListRepository = nameListRepository(nameListDao)
    private val allNames: LiveData <List<NameList>> = repository.allNames
    ...
}
NameListDao.kt

@Entity(tableName = "name_list")
data class NameList(
        @PrimaryKey(autoGenerate = true)
        var id: Long = 0L,

        @ColumnInfo(name = "name")
        var name: String = "")
@Dao
interface NameListDao{    
    @Insert
    fun insert(nameList: NameList)

    @Update
    fun update(nameList: NameList)

    @Query("SELECT * FROM name_list ORDER BY id DESC")
    fun getAll(): LiveData<List<NameList>>
}
class NameListRepository(private val nameListDao: NameListDao){
    val allNames: LiveData<List<NameList>> = nameListDao.getAll()
}
class MyViewModel(app: Application): AndroidViewModel(app){
    private val nameListDao = NameListDatabase.getInstance(app).nameListDao
    private val repository: nameListRepository = nameListRepository(nameListDao)
    private val allNames: LiveData <List<NameList>> = repository.allNames
    ...
}
MyViewModel.kt

@Entity(tableName = "name_list")
data class NameList(
        @PrimaryKey(autoGenerate = true)
        var id: Long = 0L,

        @ColumnInfo(name = "name")
        var name: String = "")
@Dao
interface NameListDao{    
    @Insert
    fun insert(nameList: NameList)

    @Update
    fun update(nameList: NameList)

    @Query("SELECT * FROM name_list ORDER BY id DESC")
    fun getAll(): LiveData<List<NameList>>
}
class NameListRepository(private val nameListDao: NameListDao){
    val allNames: LiveData<List<NameList>> = nameListDao.getAll()
}
class MyViewModel(app: Application): AndroidViewModel(app){
    private val nameListDao = NameListDatabase.getInstance(app).nameListDao
    private val repository: nameListRepository = nameListRepository(nameListDao)
    private val allNames: LiveData <List<NameList>> = repository.allNames
    ...
}
据我所知,在
ViewModel
中,需要使用
Transformations.map
Transformations.switchMap
来处理
LiveData
。 为了获取数据库的最后一个条目并将其传递给方法
doSomethingWithName()
,我尝试了以下两(四)种转换方法(都不起作用)。但是,在所有情况下,传递的参数显然都是空的。(我还通过
[0]
尝试了第一个条目,但得到了相同的结果)

类MyViewModel(应用程序:应用程序):AndroidViewModel(应用程序){
private val nameListDao=NameListDatabase.getInstance(app.nameListDao)
私有val存储库:nameListRepository=nameListRepository(nameListDao)
private val allNames:LiveData=repository.allNames
private var_lastName=“”
初始化{
map(allNames,::getLastName1)//第一次尝试
//switchMap(allNames,::getLastName2)//第二次尝试
doSomethingWithName(_lastName)//在getLastName()中执行时注释
}
private fun doSomethingWithName(名称:String){…}
私人娱乐getLastName1(名称列表:List){
val名称:MutableList=ArrayList()
nameList.forEach{names.add(it.name)}
val lastName=names[names.lastIndex]
//doSomethingWithName(lastName)//第三次尝试
_lastName=lastName
}
private fun getLastName2(名称列表:List):LiveData{
val liveData:MutableLiveData=MutableLiveData(nameList[nameList.lastIndex])
val lastName=liveData.value!!.name
//doSomethingWithName(lastName)//第四次尝试
_lastName=lastName
返回实时数据
}
}

我错过了什么

如果要获取列表中的最后一个值,请考虑列表也可能为空

class MyViewModel(app: Application): AndroidViewModel(app){
    private val nameListDao = NameListDatabase.getInstance(app).nameListDao
    private val repository: nameListRepository = nameListRepository(nameListDao)
    private val allNames: LiveData <List<NameList>> = repository.allNames
    private var _lastName = ""

    private val theLatestName =  MutableLiveData<NameList?>()
    init {
       allNames.observe(getAReferenceToaLifeCycleOwner, Observer{
         theLastestName.postValue(it.lastOrNull())
       })
       //make sure to get rid of the observer once this instance
       //of the viewmodel is destroyed
    }
类MyViewModel(应用程序:应用程序):AndroidViewModel(应用程序){
private val nameListDao=NameListDatabase.getInstance(app.nameListDao)
私有val存储库:nameListRepository=nameListRepository(nameListDao)
private val allNames:LiveData=repository.allNames
private var_lastName=“”
private val theLatestName=MutableLiveData()
初始化{
AllName.observe(getAReferenceToaLifeCycleOwner,Observer{
最新的name.postValue(it.lastOrNull())
})
//请确保在创建此实例后立即删除观察者
//viewmodel的属性被破坏
}

}

所以,基本上,我需要观察者在任何情况下。当我多次读到不应该在ViewModel中使用它,因此尝试不使用它时,我感到困惑。这是错误的。在文档中,“但是ViewModel对象决不能观察到生命周期感知的可观察对象(如LiveData对象)的更改”不应该
NameListDatabase.getInstance(app).nameListDao
在后台线程上执行吗?它会初始化(以及可能的升级)数据库,不是吗?是单音吗?如果它在UI线程上是安全的,请向我展示它的实现。我这样问是因为需要在UI线程上运行
Transformations.mapTransformations.map
,而对于DB,至少应该在后台线程上完成初始化/升级。