iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0

https://ithelp.ithome.com.tw/upload/images/20220912/20151958IFjRs0xIZ4.png Medium 好讀版

此系列文章是以我的業餘專案: Kimoji 作為範例。
這款以純 Jetpack Compose 撰寫的 side project,已經在 Google Play 上架。 歡迎試玩!

https://ithelp.ithome.com.tw/upload/images/20220907/20151958vXuPLv4aki.png 立馬下載 https://ithelp.ithome.com.tw/upload/images/20220907/20151958LtM1NGErzK.png 限免兌換碼

Composable 在 Composition 中的 instance 是由它的 call site 決定。Compose compiler 會將每個 call site 視為是相異的。從多個 call site 去呼叫 composable,會在 Composition 中建立多個 composable instance。

重要詞彙: call site 是指在 code 中呼叫 composable 的位置。而這會影響 composable 元件在 Composition 結構中的位置,進而影響 UI 樹狀結構。

如果在 recomposition 期間,composable 呼叫了一些和上一次 composition 不同的 composable,Compose 會辨識哪些 composable 上次有被呼叫過,並且對於在兩次 composition 中都有被呼叫的 composable,如果它們的 inputs 維持不變的情況下,Compose 會略過 recomposition

來參考以下範例:

@Composable
fun LoginScreen(showError: Boolean) {
    if (showError) {
        LoginError()
    }
    LoginInput() // This call site affects where LoginInput is placed in Composition
}

@Composable
fun LoginInput() { /* ... */ }

在上面的程式碼中,LoginScreen 會以根據條件呼叫 LoginError composable,並且一律呼叫 LoginInput composable。每個呼叫都有專屬的 call site 和來源位置,compiler 將會用這來識別 caller identity。
當狀態發生改變且 recomposition 觸發時,LoginScreen 在 Composition 中的示意圖。相同顏色則表示沒有被 recompose。
在第一次 composition 中, LoginInput 是第一個被呼叫的函式,而在第二次 composition 中是第二的被呼叫的函式。雖然呼叫順序改變,但 LoginInput 的 instance 在 recomposition 後仍會保留在 composition 中。此外,由於 recomposition 時,LoginInput 沒有改變任何參數,因此 Compose 會略過對 LoginInput 的呼叫。換句話說,也就是 recomposition 時,LoginInput 不會重新執行一次。

此系列文章是以我的業餘專案:Kimoji 為範例。

Kimoji 是一款心情日記 App,讓你用可愛的 emoji 來撰寫你的心情日記。現在就來試試這款設計精美的微日記吧!

https://ithelp.ithome.com.tw/upload/images/20220907/20151958vXuPLv4aki.png 立馬下載 https://ithelp.ithome.com.tw/upload/images/20220907/20151958LtM1NGErzK.png 限免兌換碼

Reference: https://developer.android.com/jetpack/compose/lifecycle


上一篇
Composables 的 lifecycle
下一篇
Jetpack Compose 中的 state mutation
系列文
Kimoji:以 Jetpack Compose 實作一款「心情日記」應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言