假設我們有以下代碼。它顯示一個按鈕,當用戶單擊它時,該按鈕消失。
@Composable
fun ButtonThatDisappearsOnClick() {
var showButton by remember { mutableStateOf(true) }
if (showButton) {
Button(onClick = {
check(showButton) { "onClick shouldn't be called for a hidden button" } // !!!
showButton = false
}) {
Text("My button")
}
}
}
我懷疑如果用戶非常快速地check單擊按鈕兩次,上面的呼叫可能會失敗:
- 用戶點擊按鈕,
shouldShowButton設定為false。由于可變狀態的值已更新,因此安排了重組。 - 在重新組合視圖之前,用戶再次非常快速地單擊該按鈕。因此,該
onClick函式將第二次觸發,check呼叫將失敗。
我無法在實踐中重現這一點,所以我想知道這種行為是否確實可能。
uj5u.com熱心網友回復:
這個問題是回答你所要求的。Op 連續更改值,但如果在重組完成之前狀態值發生變化,則可能會丟棄先前的重組并安排新的重組。
如果連續設定兩個值,MutableState 會忽略第一個值
SideEffect函式可用于僅在成功重組發生時才應呼叫的操作
每當 Compose 認為可組合項的引數可能已更改時,就會開始重新組合。重組是樂觀的,這意味著 Compose 期望在引數再次更改之前完成重組。如果在重組完成之前引數確實發生了變化,Compose 可能會取消重組并使用新引數重新啟動它。
取消重組后,Compose 會從重組中丟棄 UI 樹。如果您有任何依賴于正在顯示的 UI 的副作用,即使取消合成也會應用副作用。這可能會導致應用程式狀態不一致。
確保所有可組合函式和 lambda 都是冪等且無副作用的,以處理樂觀重組。
uj5u.com熱心網友回復:
有可能的。不太可能發生,但有可能。實際上,compose中存在快速單擊或雙擊問題。在這種特殊情況下,這可能會發生,因為可組合的示例保持某種狀態。
有一種做法是使可組合的無狀態,并將狀態保留在外部。Compose 將能夠檢測特定重組流程之外的引數變化,并可能取消它。(在您的情況下,它不會隱藏按鈕,因此您不會遇到意外行為)
來自官方檔案
每當 Compose 認為可組合項的引數可能已更改時,就會開始重新組合。重組是樂觀的,這意味著 Compose 期望在引數再次更改之前完成重組。如果在重組完成之前引數確實發生了變化,Compose 可能會取消重組并使用新引數重新啟動它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/523275.html
標籤:安卓多线程科特林android-jetpack-compose竞争条件
上一篇:同一程式中的馬虎計數器和多個鎖
