iT邦幫忙

2022 iThome 鐵人賽

DAY 11
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 限免兌換碼

Compose 可以同時執行多個 composable function,將 recomposition 最佳化。因此,Compose 得以利用多核心,並以較低優先順序執行不在螢幕畫面上的 composable functions。

這項最佳化意味著 composable function 可能會在 background thread pool 中執行。如果 composable function 呼叫 ViewModel 中的某個函式,Compose 可能會同時從多個 thread 呼叫該函式。

為了確保 app 正確運作,所有 composable function 都不得有 side-effect。如需觸發 side-effect,要改用 callback,例如一個在 UI thread 上執行的 onClick

Composable function 被呼叫時,function call 可能是執行在與 caller 不同的 thread 上。因此,應避免修改 composable lambda 裡的變數,一來這樣無法確保 thread-safe,而且對 composable lambda 來說這樣會是 side-effect。

下面範例中的 composable 會顯示「日記本」及「日記篇數」:

@Composable
fun Journal(diaries: List<String>) {
    Row(horizontalArrangement = Arrangement.SpaceBetween) {
        Column {
            for (diary in diaries) {
                Text(diary)
            }
        }
        Text("Count: ${diaries.size}")
    }
}

這段程式碼沒有任何 side-effect,並會將「日記清單」轉換為 UI,很適合用來顯示小型列表。不過,如果函式會修改 local variable,這段程式碼就無法確保 thread-safe,或是正確性:

@Composable
@Deprecated("Example with bug")
fun JournalWithBug(diaries: List<String>) {
    var items = 0

    Row(horizontalArrangement = Arrangement.SpaceBetween) {
        Column {
            for (diary in diaries) {
                Text(diary)
                items++ // Avoid! Side-effect of the column recomposing.
            }
        }
        Text("Count: $items")
    }
}

在這個範例中,items 會隨著每次 recomposition 而被修改。修改時機可能是在動畫中的每個 frame 或是在傳進來的「日記清單」被更新時。無論如何,UI 都會顯示錯誤的「日記篇數」。因此,Compose 不支援這種修改;藉由禁止這種修改,Compose 才得以切換 thread 來執行 composable lambda。

此系列文章是以我的業餘專案: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/mental-model


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

尚未有邦友留言

立即登入留言