ViewModel实例化导致无限循环

时间:2019-08-29 03:48:36

标签: android mvvm android-viewmodel

我使用的是在实例化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()上。

我看不到循环的创建位置。感谢您的帮助。

1 个答案:

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