我使用的是在实例化ViewModel
对象之前使用过几次的模式。在这种情况下,数据将以字符串形式保存在SharedPreferences
中。我只需要读取该字符串,将其解析为正确的对象,然后将该对象作为值分配给我的视图模型即可。
但是当我进行分配时,我会创建一个无限循环。
class UserDataViewModel(private val prefs: SharedPreferences): ViewModel() {
val userData: MutableLiveData<UserData> by lazy {
MutableLiveData<UserData>().also {
val userDataString = prefs.getString(Authenticator.USER_DATA, "")
val ud = Gson().fromJson(userDataString, UserData::class.java)
userData.value = ud // infinite loop is here
}
}
fun getUserData(): LiveData<UserData> {
return userData
}
}
这位于保留对onCreateView()
的引用的片段的ViewModel
中:
userDataViewModel = activity?.run {
ViewModelProviders
.of(this, UserDataViewModelFactory(prefs))
.get(UserDataViewModel::class.java)
} ?: throw Exception("Invalid Activity")
userDataViewModel
.getUserData()
.observe(this, Observer {
binding.userData = userDataViewModel.userData.value
})
FWIW,在片段中,我在getUserData()
和binding.userData...
上都有断点。命中的最后一个断点在getUserData()
上。
我看不到循环的创建位置。感谢您的帮助。
答案 0 :(得分:3)
仅在userData
块返回后才初始化by lazy {}
字段。您正在userData
块中访问by lazy {}
字段,这就是创建循环的原因-内部访问会看到它尚未完成初始化,因此它将再次运行该块。
相反,您可以使用MutableLiveData
而不是also
来访问it
块中正在修改的userData
,从而打破循环:
val userData: MutableLiveData<UserData> by lazy {
MutableLiveData<UserData>().also {
val userDataString = prefs.getString(Authenticator.USER_DATA, "")
val ud = Gson().fromJson(userDataString, UserData::class.java)
it.value = ud
}
}