首页
搜索 搜索
资讯

Compose到底什么时候会触发重组?

2023-02-23 07:15:06 哔哩哔哩

过程太长直接说结论:

对于MutableState,包括用LiveData,Flow转过来的State,唯一能够触发重组的时机是值被覆盖,或者更准确一点:容器里面的对象的内存地址的改变。


【资料图】

反面典型是:var li by remember{(mutableStateOf(List()))}

你去调用li的任何函数都无法触发重组,因为它的地址没有变过。

这是触发重组的一方,还有一个问题是哪些部分会被重组——因为重组是乐观的操作,换句话说Compose会避免不必要的重组,所以需要知道哪些操作不会被避免。

简单说就是一切给可组合项的参数赋值的操作,都会参与重组的过程。

必须是直接把一个state的值赋给可组合项的参数才可以,反面例子是:

赋值给不是可组合项参数的对象是不会参与重组的,即使去掉s直接调用也不会触发,因为最终使用的时候没有调用到setter的getter。

所以一句话总结就是,跟重组这个操作挂钩的只有State的Setter跟Getter,其余一切操作均无关。 但是如果把s.contains改成if(s==null),就会触发重组,因为调用了getter。

但有的时候又确实需要其它操作来触发重组,比如文件管理器的多选,根据单一来源原则Checkbox是否被选择这个状态只依赖于Set中是否存在当前文件,用MutableState怎么都触发不了重组,虽然也有办法摁是去触发一次重组来更新Checkbox的状态,但那样就跟View体系没区别了,不符合Compose的思想。

于是SnapshotStateList诞生了,这是源文档的介绍:

Create a instance of MutableList that is observable and can be snapshot.

我不理解。什么叫Snapshot,我在Windows里面用过类似命名的函数是用来读取当前进程注入dll之类的,但是在Compose语境下快照是什么意思我还是不理解。

但这不重要,就像我也不理解MD5的具体算法,但我知道它能做什么。

SnapshotStateList是一个List,也是一个可以用add,remove一类的操作触发重组的State。

以上