Compose到底什么時(shí)候會(huì)觸發(fā)重組?
過程太長(zhǎng)直接說結(jié)論:
對(duì)于MutableState,包括用LiveData,Flow轉(zhuǎn)過來(lái)的State,唯一能夠觸發(fā)重組的時(shí)機(jī)是值被覆蓋,或者更準(zhǔn)確一點(diǎn):容器里面的對(duì)象的內(nèi)存地址的改變。
反面典型是:var li by remember{(mutableStateOf(List()))}
你去調(diào)用li的任何函數(shù)都無(wú)法觸發(fā)重組,因?yàn)樗牡刂窙]有變過。
這是觸發(fā)重組的一方,還有一個(gè)問題是哪些部分會(huì)被重組——因?yàn)橹亟M是樂觀的操作,換句話說Compose會(huì)避免不必要的重組,所以需要知道哪些操作不會(huì)被避免。
簡(jiǎn)單說就是一切給可組合項(xiàng)的參數(shù)賦值的操作,都會(huì)參與重組的過程。
必須是直接把一個(gè)state的值賦給可組合項(xiàng)的參數(shù)才可以,反面例子是:
賦值給不是可組合項(xiàng)參數(shù)的對(duì)象是不會(huì)參與重組的,即使去掉s直接調(diào)用也不會(huì)觸發(fā),因?yàn)樽罱K使用的時(shí)候沒有調(diào)用到setter的getter。
所以一句話總結(jié)就是,跟重組這個(gè)操作掛鉤的只有State的Setter跟Getter,其余一切操作均無(wú)關(guān)。?但是如果把s.contains改成if(s==null),就會(huì)觸發(fā)重組,因?yàn)檎{(diào)用了getter。
但有的時(shí)候又確實(shí)需要其它操作來(lái)觸發(fā)重組,比如文件管理器的多選,根據(jù)單一來(lái)源原則Checkbox是否被選擇這個(gè)狀態(tài)只依賴于Set中是否存在當(dāng)前文件,用MutableState怎么都觸發(fā)不了重組,雖然也有辦法摁是去觸發(fā)一次重組來(lái)更新Checkbox的狀態(tài),但那樣就跟View體系沒區(qū)別了,不符合Compose的思想。
于是SnapshotStateList誕生了,這是源文檔的介紹:
Create a instance of MutableList that is observable and can be snapshot.
我不理解。什么叫Snapshot,我在Windows里面用過類似命名的函數(shù)是用來(lái)讀取當(dāng)前進(jìn)程注入dll之類的,但是在Compose語(yǔ)境下快照是什么意思我還是不理解。
但這不重要,就像我也不理解MD5的具體算法,但我知道它能做什么。
SnapshotStateList是一個(gè)List,也是一個(gè)可以用add,remove一類的操作觸發(fā)重組的State。
以上