Android 观察变量和函数有什么区别

Android 观察变量和函数有什么区别,android,kotlin,mvvm,viewmodel,android-architecture-components,Android,Kotlin,Mvvm,Viewmodel,Android Architecture Components,当我从片段A观察到viewmodel中的一个变量时 val fetchTopicsList = liveData(Dispatchers.IO) { emit(Resource.Loading()) try { emit(repo.getIdeas()) }catch (e:Exception){ emit(Resource.Failure(e)) } } 我导航到片段B,然

当我从片段A观察到viewmodel中的一个变量时

val fetchTopicsList = liveData(Dispatchers.IO) {
        emit(Resource.Loading())
        try {
            emit(repo.getIdeas())
        }catch (e:Exception){
            emit(Resource.Failure(e))
        }
    }
我导航到片段B,然后返回片段A,观察者将再次触发,但新数据不会被提取

现在,如果我将该声明更改为函数声明

fun fetchTopicsList() = liveData(Dispatchers.IO) {
        emit(Resource.Loading())
        try {
            emit(repo.getIdeas())
        }catch (e:Exception){
            emit(Resource.Failure(e))
        }
    }
当我执行相同的操作(从片段A转到片段B,然后返回)时,观察者将再次触发,并再次从服务器中提取数据


为什么函数会再次激发,而变量只保留第一次获取的数据?

您可能实际上想要一个
MutableLiveData
的实例,该实例在某些交互中发出,但我想直接回答您的问题:

使用该函数,每次调用都将为您提供一个新的
LiveData
实例,而在实例化类时,使用属性初始值设定项将实例化并将其设置为
LiveData
的单个实例。这意味着,如果您的属性位于
ViewModel
上,它将在配置更改和暂停/恢复周期中继续存在,直到被销毁

如果您更喜欢属性语法,可以通过重写getter使其执行与每次重新调用函数相同的操作,但老实说,函数在语法上更精确

以下是使用属性语法实现相同功能的方法:

val fetchTopicsList: LiveData<..>
  get() = liveData(Dispatchers.IO) {
     emit(Resource.Loading())
     try {
       emit(repo.getIdeas())
     } catch (e:Exception){
       emit(Resource.Failure(e))
     }
  }
val fetchTopicsList:LiveData
get()=liveData(Dispatchers.IO){
发出(Resource.Loading())
试一试{
emit(repo.getIdeas())
}捕获(e:例外){
发射(资源故障(e))
}
}

同样,更好的方法可能是使用单个
MutableLiveData
并在
ViewModel
上公开一个函数,以便为任何订阅者发出请求并发布值。

通常,您希望将LiveData缓存为字段,“refetch”应该由LiveData本身触发,使用
emitSource
收听。