Android ViewModel如何缓存LiveData?

Android ViewModel如何缓存LiveData?,android,kotlin,viewmodel,android-livedata,Android,Kotlin,Viewmodel,Android Livedata,我在Google的Codelabs和其他来源的不同示例项目中看到了以下所有场景,但我并不完全理解从何处检索LiveData对象的值 情景1——目前的理解: 使用ViewModel的一个原因是存储/缓存与UI相关的数据,在配置更改后重建相应的UI后,这些数据要重新使用 给定以下简化的ViewModel和Repository:updateName()第一次调用后,_currentName的LiveData对象包含一个字符串。如果在屏幕旋转后重建UI,则需要显示当前名称的视图会通过观察currentN

我在Google的Codelabs和其他来源的不同示例项目中看到了以下所有场景,但我并不完全理解从何处检索LiveData对象的值

情景1——目前的理解:

使用ViewModel的一个原因是存储/缓存与UI相关的数据,在配置更改后重建相应的UI后,这些数据要重新使用

给定以下简化的ViewModel和Repository:updateName()第一次调用后,_currentName的LiveData对象包含一个字符串。如果在屏幕旋转后重建UI,则需要显示当前名称的视图会通过观察currentName来请求该UI,currentName反过来会返回包含在_currentName属性字段中的LiveData对象的值。我说得对吗

视图模型

class NamesViewModel(): ViewModel() {
    
    private val respository = NamesRepository()

    private val _currentName: MutableLivedata<String?> = MutableLiveData(null)
    val currentName: LiveData<String?> get() = this._currentName

    ...

    // Called as UI event listener.
    fun updateName() {
        this._currentName.value = this.repository.updateName()
    }
}
class NamesViewModel(): ViewModel() {
    
    private val respository = NamesRepository()

    private val _currentName: LiveData<String?> = this.repository.currentName
    val currentName: LiveData<String?> get() = this._currentName

    ...

    // Called as UI event listener.
    fun updateName() {
        this.repository.updateName()
    }
}
class NamesViewModel(): ViewModel() {
    
    private val respository = NamesRepository()

    val currentName: LiveData<String?> get() = this.repository.currentName

    ...

    // Called as UI event listener.
    fun updateName() {
        this.repository.updateName()
    }
}
情景2:

在以下情况下,如果在屏幕旋转后重建UI,会发生什么情况_ViewModel中的currentName“观察”存储库中的currentName,但它仍然是一个属性,因此在其字段中存储自己的LiveData对象。然后,当视图从ViewModel请求currentName时,将从ViewModel中_currentName属性字段中包含的LiveData对象中检索该值。这是正确的吗

视图模型

class NamesViewModel(): ViewModel() {
    
    private val respository = NamesRepository()

    private val _currentName: MutableLivedata<String?> = MutableLiveData(null)
    val currentName: LiveData<String?> get() = this._currentName

    ...

    // Called as UI event listener.
    fun updateName() {
        this._currentName.value = this.repository.updateName()
    }
}
class NamesViewModel(): ViewModel() {
    
    private val respository = NamesRepository()

    private val _currentName: LiveData<String?> = this.repository.currentName
    val currentName: LiveData<String?> get() = this._currentName

    ...

    // Called as UI event listener.
    fun updateName() {
        this.repository.updateName()
    }
}
class NamesViewModel(): ViewModel() {
    
    private val respository = NamesRepository()

    val currentName: LiveData<String?> get() = this.repository.currentName

    ...

    // Called as UI event listener.
    fun updateName() {
        this.repository.updateName()
    }
}
classnamesviewmodel():ViewModel(){
private val respository=NamesRepository()
private val_currentName:LiveData=this.repository.currentName
val currentName:LiveData get()=此。\u currentName
...
//称为UI事件侦听器。
fun updateName(){
this.repository.updateName()
}
}
存储库

class NamesRepository() {
    
    fun updateName(): String {
        val nextName: String     
   
        ...

        return nextName
    }
}
class NamesRepository() {

    private val _currentName: MutableLivedata<String?> = MutableLiveData(null)
    val currentName: LiveData<String?> get() = this._currentName
    
    fun updateName() {
        val nextName: String     
   
        ...

        this._currentName.value = nextName
    }
}
class NamesRepository() {

    private val _currentName: MutableLivedata<String?> = MutableLiveData(null)
    val currentName: LiveData<String?> get() = this._currentName
    
    fun updateName() {
        val nextName: String     
   
        ...

        this._currentName.value = nextName
    }
}
类名称存储库(){
private val_currentName:MutableLivedata=MutableLivedata(null)
val currentName:LiveData get()=此。\u currentName
fun updateName(){
val nextName:String
...
此.\u currentName.value=nextName
}
}
情景3:

在下面的场景中,如果UI是重建的,并且视图从ViewModel请求currentNam,那么请求的值存储在哪里?我目前的理解是,currentName返回到存储库中属性_currentName的字段。这是否违背了ViewModel存储相关UI数据以在配置更改后重复使用的想法?在下面的例子中,从存储库而不是从viewModel中检索值可能没有问题,但是如果存储库本身直接从房间数据库中的LiveData对象检索值呢?不是每次视图从viewModel请求_currentName时都会进行数据库访问吗

我希望有人能进一步澄清这种情况,以便理解如何以正确的方式在viewModel中缓存与UI相关的数据(或者至少理解哪些是不正确的方式)

视图模型

class NamesViewModel(): ViewModel() {
    
    private val respository = NamesRepository()

    private val _currentName: MutableLivedata<String?> = MutableLiveData(null)
    val currentName: LiveData<String?> get() = this._currentName

    ...

    // Called as UI event listener.
    fun updateName() {
        this._currentName.value = this.repository.updateName()
    }
}
class NamesViewModel(): ViewModel() {
    
    private val respository = NamesRepository()

    private val _currentName: LiveData<String?> = this.repository.currentName
    val currentName: LiveData<String?> get() = this._currentName

    ...

    // Called as UI event listener.
    fun updateName() {
        this.repository.updateName()
    }
}
class NamesViewModel(): ViewModel() {
    
    private val respository = NamesRepository()

    val currentName: LiveData<String?> get() = this.repository.currentName

    ...

    // Called as UI event listener.
    fun updateName() {
        this.repository.updateName()
    }
}
classnamesviewmodel():ViewModel(){
private val respository=NamesRepository()
val currentName:LiveData get()=this.repository.currentName
...
//称为UI事件侦听器。
fun updateName(){
this.repository.updateName()
}
}
存储库

class NamesRepository() {
    
    fun updateName(): String {
        val nextName: String     
   
        ...

        return nextName
    }
}
class NamesRepository() {

    private val _currentName: MutableLivedata<String?> = MutableLiveData(null)
    val currentName: LiveData<String?> get() = this._currentName
    
    fun updateName() {
        val nextName: String     
   
        ...

        this._currentName.value = nextName
    }
}
class NamesRepository() {

    private val _currentName: MutableLivedata<String?> = MutableLiveData(null)
    val currentName: LiveData<String?> get() = this._currentName
    
    fun updateName() {
        val nextName: String     
   
        ...

        this._currentName.value = nextName
    }
}
类名称存储库(){
private val_currentName:MutableLivedata=MutableLivedata(null)
val currentName:LiveData get()=此。\u currentName
fun updateName(){
val nextName:String
...
此.\u currentName.value=nextName
}
}

回答您的问题
场景#1
正确使用
LiveData

首先,
LiveData
不负责缓存,它只是可以观察到的LifeCycleAware,因为缓存是在
ViewModel
上完成的,当您的
活动由于任何配置更改而重新创建时,android将尝试检索
ViewModel
的现有实例,如果找到,则它的状态和数据将按原样保留,否则它将创建
ViewModel
的新实例


其次,在
repository
中使用
LiveData
在很多层面上都是一个坏主意,存储库实例由
ViewModel
持有,而
LiveData
是Android框架的一部分,这使得存储库依赖于Android框架,从而在单元测试中产生问题。始终仅在
视图模型中使用
LiveData
来回答您的问题
场景#1
是否正确使用
LiveData

首先,
LiveData
不负责缓存,它只是可以观察到的LifeCycleAware,因为缓存是在
ViewModel
上完成的,当您的
活动由于任何配置更改而重新创建时,android将尝试检索
ViewModel
的现有实例,如果找到,则它的状态和数据将按原样保留,否则它将创建
ViewModel
的新实例

其次,在
repository
中使用
LiveData
在很多层面上都是一个坏主意,存储库实例由
ViewModel
持有,而
LiveData
是Android框架的一部分,这使得存储库依赖于Android框架,从而在单元测试中产生问题。始终仅在视图模型中使用
LiveData