Android Jetpack Compose中全局变量myData变更后变量b为何不更新?
问题描述
定义了全局变量var myData=0,在Android Jetpack Compose的ScreenHome可组合函数中,点击按钮时变量a正常递增,但变量b始终保持0不变。原以为给remember设置myData作为key后,var b by remember(myData){ mutableStateOf(myData) }会在myData变更时重新计算,却没达到预期。
问题代码
ScreenHome.kt
@Composable fun ScreenHome(){ var a by remember { mutableStateOf(1) } var b by remember(myData){ mutableStateOf(myData) } Button( onClick = { a = a + 1 myData = myData + 1 }, modifier = Modifier.fillMaxWidth() ) { Text(a.toString()+" "+b.toString()) // b始终显示0 } }
PublicPar.Kt
var myData=0
原因分析
remember的key参数能触发重新计算的前提是:Compose能感知到key的变化。但你定义的myData是普通全局变量,不是Compose的状态变量(即没有用mutableStateOf这类API包装),所以当myData的值改变时,Compose完全检测不到这个变化,自然不会重新执行remember的初始化逻辑,b也就一直停留在初始值0。
而a能正常更新,是因为它是用mutableStateOf包装的状态变量,Compose会自动监听这类变量的变化,触发重组并更新UI。
解决方案
方案一:把全局变量改成Compose状态变量(推荐)
将myData改用mutableStateOf包装,让Compose能感知它的变化:
// PublicPar.Kt var myData by mutableStateOf(0)
这样原ScreenHome的代码不需要修改,当myData更新时,remember(myData)的key发生变化,Compose会重新计算b的初始值,UI也会同步更新。
方案二:手动触发重组(不推荐)
如果一定要保留普通全局变量,可以在修改myData后手动触发Activity重建,但这种方式性能开销大,不符合Compose的状态管理规范,容易引发问题:
@Composable fun ScreenHome(){ val context = LocalContext.current var a by remember { mutableStateOf(1) } var b by remember(myData){ mutableStateOf(myData) } Button( onClick = { a = a + 1 myData = myData + 1 // 手动触发整个Activity重建 (context as ComponentActivity).recreate() }, modifier = Modifier.fillMaxWidth() ) { Text(a.toString()+" "+b.toString()) } }
内容的提问来源于stack exchange,提问作者HelloCW

