【发布时间】:2021-09-09 16:08:35
【问题描述】:
我的主屏幕有以下代码:
@Composable
fun MainScreen() {
val viewModel = getViewModel<MainViewModel>()
val tasks: List<Task> by viewModel.taskList.observeAsState(listOf())
LazyColumn(contentPadding = PaddingValues(bottom = 96.dp)) {
items(tasks) { task ->
if (task == tasks[0]) {
ListItemActive(task = task)
} else {
ListItemInactive(task = task)
}
}
}
val isInProgress: Boolean by viewModel.isInProgress.observeAsState(false)
if (isInProgress) {
Preloader()
}
}
导航在主要活动中管理,如下所示:
NavHost(navController = navController, startDestination = Screen.Main.route) {
composable(Screen.Login.route) { LoginScreen() }
composable(Screen.Main.route) { MainScreen() }
}
问题是,每当我在 android studio 中调整填充或其他尺寸时,我的主屏幕构图都会被重新评估。这是人们所期望的,但不是采用现有的视图模型,而是创建了新的视图模型。旧的不调用 onCleared 。这是预期的行为,还是我遗漏了什么?
编辑: 当对代码进行任何更改并且实时编辑器尝试在模拟器上更新它们时,我也会遇到崩溃。
例外:读取在拍摄快照后或尚未应用的快照中创建的状态
当访问 SharedPreferences 时,它发生在下面的代码中。此代码从视图模型中的 init 块调用,该块在代码填充更改期间第二次初始化。
httpClient.addInterceptor { chain ->
val request: Request = chain
.request()
.newBuilder()
.addHeader("Authorization", "Bearer ${get<PreferenceRepository>().accessToken}")
.build()
chain.proceed(request)
}
虽然它似乎与我正在使用的 viewModelScope 相关联。将其替换为 GlobalScope 可防止应用崩溃。
【问题讨论】:
-
一个小提示:您可以使用
itemsIndexed代替items并比较index而不是项目本身。 -
您是说在您启动应用程序,然后在代码中更新
PaddingValues,并且您的应用程序在没有重新启动的情况下更新?最有可能的是,在这种情况下,旧的视图模型将被简单地杀死,如果您在应用程序的正常运行期间没有遇到类似的问题,您无需担心。 -
@PhilipDukhov,感谢您的提示。是的,情况确实如此,尽管我实际上遇到了问题。我的应用程序因“读取在拍摄快照后创建的状态或在尚未应用的快照中创建的状态”而崩溃,这似乎是由访问视图模型的 init() 块中的共享首选项引起的。
-
我相信它叫做
Enable Live Edit of literals,请尝试在 AS 偏好设置中禁用它。 -
@PhilipDukhov,是的,但我希望能够使用它,因为它极大地提高了我的工作效率。现在,我只是在应用设计时注释掉了我的视图模型的 init() 方法。但我仍然想找到一个更永久的解决方案。
标签: android android-jetpack-compose koin