视图模型实例化会导致无限循环



我正在使用一种我以前使用过几次的模式来实例化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
}
}

这是保留对ViewModel引用的片段onCreateView()

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()上。

我没有看到循环的创建位置。感谢您的任何帮助。

只有在by lazy {}块返回后,才会初始化userData字段。您正在从by lazy {}块内访问userData字段,这就是创建循环的原因 - 内部访问看到它尚未完成初始化,因此它再次运行该块。一次又一次。

相反,您可以使用it而不是userData来访问您在also块中修改的MutableLiveData,打破循环:

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
}
}

最新更新