为什么 ViewModel 方法引用不稳定(导致重组),而 lambda 却稳定?(Jetpack 撰写)

Rob*_*bin 11 android kotlin android-jetpack-compose compose-recomposition

我有一个 MVI 架构,其中包含主屏幕的活动

class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      MyTheme {
        val viewModel: MainScreenViewModel = viewModel(factory = MainScreenViewModel.Factory)
        val state by viewModel.viewState.collectAsState()
        MainScreen(state, viewModel::handleEvent)
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

主屏幕看起来有点像这样:

@Composable
fun MainScreen(state: MainScreenState, onEvent: (Event) -> Unit) {
  TaskList(
    tasks = state.items,
    onEvent = onEvent,
  )
}

@Composable
fun TaskList(tasks: List<TaskState>, onEvent: (Event) -> Unit) {
  LazyColumn {
    items(items = tasks, key = { it.id }) {
      Task(state = it, onEvent = onEvent)
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果 ViewModel 发出一个新的MainScreenState更改TaskState,则TaskList重新组合。这是预期的,因为传递了一个新的列表对象。不仅更改的内容Task被重新组合,列表中的每个Task可组合项也被重新组合。造成这种情况的原因不是TaskState,而是稳定。

导致重组的似乎是回调onEvent。如果我更改为onEvent = onEvent,问题就解决了。但我不明白为什么。方法引用不应该也是稳定的吗?我什至检查了 hashCode,它总是相同的。onEvent = { onEvent(it) }MainScreen

小智 1

您需要查看发布模式下的重组次数,而不是调试模式下的重组次数。

我不知道为什么,但感谢这篇文章 https://itnext.io/exercises-in-futility-jetpack-compose-recomposition-6ea3cf9bc1b4

https://github.com/theapache64/rebugger

我发现 lambda 在发布中是稳定的。

问题是编译器处于调试模式