android - ViewModel实例化导致死循环

标签 android mvvm android-viewmodel

我正在使用我之前使用过几次的模式来实例化 ViewModel 对象。在这种情况下,数据在 SharedPreferences 中保存为字符串。我只需要读取该字符串,将其解析为正确的对象,然后将该对象作为值分配给我的 View 模型。

但是当我做作业时,我创建了一个无限循环。

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 的引用的 fragment 的 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,在 fragment 中,我在 getUserData()binding.userData... 上都有断点。命中的最后一个断点在 getUserData() 上。

我没有看到循环是在哪里创建的。感谢您的帮助。

最佳答案

userData字段仅在 by lazy {} 后初始化 block 返回。您正在访问 userData来自 by lazy {} 的字段 block ,这就是创建循环的原因 - 内部访问发现它尚未完成初始化,因此它再次运行该 block ......一次又一次。

相反,您可以访问 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
    }
}

关于android - ViewModel实例化导致死循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57702720/

相关文章:

android - 如何使用一个 ViewModelFactory 为 Dagger 提供所有 ViewModel

java - 在所有 Android 版本中以编程方式打开和关闭 GPS

android - API 17 和 API 16 中的 RecyclerView 高度问题 - Android

c# - 使用 MVVM 更改按钮 BackgroundColor

android - 如何使用 ViewModel(MVVM) 将对象从 fragment 传递到 Activity 详细信息 View ?

android - 从 ViewModel 观察 LiveData

android - 在主应用程序和库中使用 Realm

android - 在 Flutter 中改变方向时保留 TextField 值

silverlight-4.0 - 展开项目与选定项目不同

android - 使用Android MVVM,如何避免在回收站适配器中再次设置相同的数据?