true
可保證只執行一次。rememberUpdatedState
後傳入協程,可避免因 UI State 變動而延長或重啟作業;若忽視此作法,容易導致行為與預期不符。在 Composable
內啟動一段與 UI 生命週期綁定的 Coroutine
。只有依賴值改變時才會重新啟動,離開 Composition 時自動取消。
當使用者切換到不同播放清單 playlistId
時,使用
確保僅在 ID 改變時才重新向伺服器抓取曲目,避免多餘請求;若使用者迅速返回上一清單,協程亦會被取消,節省流量與電量。
在 Composable 中記住一個可用於啟動長生命週期工作的 CoroutineScope
;Scope 會隨組件離開 Composition 一併取消。
「下載專輯」按鈕需要背景下載多首歌曲並持續顯示進度:
可避免因連點造成多支協程同時下載;Component 消失時自動終止未完成下載,防止殘留任務。
將最新的 value 封裝進 State<T>
,讓仍在執行的協程或回呼存取到最新值,而不需重新重組。常用於 LaunchedEffect
內部或回呼引用。
播放進度通知使用者偏好語言:
避免語系變更後仍顯示舊語言時間格式。
在進入 Composition 時執行初始化,並在離開時執行清理邏輯。適合與系統 listener、廣播或第三方 API 綁定/解除。
註冊並釋放耳機插拔廣播:
確保畫面關閉或組件銷毀時不遺留 Receiver,避免記憶體滲漏。
在每次成功重組後執行一次同步函式;不屬於協程,主要用於與外部物件保持一致(例如測量、日誌)。
將目前可見曲目 ID 同步到原生 Android Window 標題(供多工檢視顯示):
重組時若 currentTrack
變化,Window 標題即時更新,而不需額外 listener。
在 Composable 內以協程「產生」一個 State<T>
,允許持續發射新值;生命週期同 Composition。
持續讀取播放器緩衝百分比並以 State
回推 UI:
玩家重啟或畫面離開時,協程自動取消,不會繼續輪詢。
根據一組 State
來源,計算出另一個只在來源變動且計算結果改變時才重組的衍生狀態;避免昂貴計算重複執行。
根據播放清單曲目與當前排序模式計算顯示列表:
tracks
未改變時改動 UI 排序不會重新下載封面,提升效能。
將連續的 Compose State
讀取封裝為 Cold Flow
,每次 snapshot 變動時發出新值,用於橋接 Compose 與非 Compose 協程 API。
監聽音量滑桿並節流寫入偏好:
Compose Slider 變化頻繁,但只在使用者停止拖動 300 ms 後才寫入,避免 I/O 風暴。
這些 API 多用於處理副作用與狀態同步。若只在 Recomposition 裡做純運算,可考慮避免不必要的協程或 Effect,以減少複雜度與潛在資源浪費。
在 Jetpack Compose 中,何謂「副作用」(side effect)?
A. 只在預覽模式下執行的程式碼
B. 超出 Composable 函式範圍、影響外部狀態或資源的操作
C. 造成版面配置錯亂的 UI 變動
D. 任何耗費 CPU 的運算
答案:B
為何不應該直接在 Composable 函式主體內呼叫網路 API?
A. Composable 無法存取網路
B. 可能造成 UI thread 崩潰
C. 每次重組(recomposition)都會再次執行呼叫,難以控制次數
D. 會違反 Android 6.0 之後的權限規範
答案:C
LaunchedEffect 能夠執行 suspend 函式的主要原因是什麼?
A. 其內部隱含了一個 CoroutineScope
B. 編譯器會把 suspend 函式改寫成同步
C. Compose runtime 會自動暫停主執行緒
D. LaunchedEffect 預設使用 ThreadPoolExecutor
答案:A
當傳入 LaunchedEffect 的 key 參數改變時,系統會如何處理?
A. 忽略新值,維持舊協程
B. 取消舊協程並重新啟動區塊
C. 立即關閉畫面
D. 只執行一次新的協程而不取消舊的
答案:B
若對 LaunchedEffect 傳入固定值 true 作為 key,代表該區塊會如何執行?
A. 只在首度進入 Composition 時執行一次
B. 每次重組皆執行
C. 完全不會執行
D. 只在畫面旋轉時執行
答案:A
在 ViewModel 內以 SharedFlow 傳遞事件到 UI,於 Composable 中使用 LaunchedEffect 收集的好處為?
A. 可以在背景執行緒更新 UI
B. 避免因重組而重複 collect,確保只收集一次
C. 自動快取事件歷史
D. 免去權限檢查流程
答案:B
若在 Composable 函式主體直接呼叫 collect(),最大風險是?
A. collect 會被忽略
B. Flow 會停止發射
C. 每次重組都重新收集,導致記憶體與執行緒浪費
D. 編譯不會通過
答案:C
rememberCoroutineScope 所回傳的 CoroutineScope 具有什麼生命週期?
A. 與整個應用程式存活時間相同
B. 與當前 Composable 的 Composition 存活時間相同,離開時自動取消
C. 與 Activity 相同
D. 與 ViewModel 相同
答案:B
哪一個場合最適合使用 rememberCoroutineScope?
A. 在 onClick 回呼中啟動短暫的協程
B. 長時間的資料同步作業
C. 循環播放音樂服務
D. 伴隨應用程式整體生命週期的監控
答案:A
在按鈕 onClick 裡啟動協程時,以下何者為最佳寫法?
A. GlobalScope.launch { … }
B. rememberCoroutineScope().launch { … }
C. Thread { … }.start()
D. LaunchedEffect(key1 = Unit) { … }
答案:B
為何不建議在 Composable 外層大量使用 rememberCoroutineScope 啟動長任務?
A. Compose 不支援協程
B. 該 Scope 只活在 UI 層,長任務更適合 ViewModelScope
C. Kotlinx.coroutines 不穩定
D. 會強制使用主執行緒
答案:B
rememberUpdatedState 的功能是?
A. 固定某個狀態值不再更新
B. 提供可變的 State,避免觸發重組
C. 在 effect 區塊中取得最新的參數或 lambda 引用,而不重新啟動協程
D. 建立具自動取消能力的 Channel
答案:C
在啟動畫面中,若 onTimeout Lambda 可能被替換,但不希望延長計時,應怎麼做?
A. 將 onTimeout 直接放進 key
B. 使用 rememberUpdatedState 包裝 onTimeout,並保持 key 固定
C. 將計時邏輯搬到 Activity
D. 改用 Handler.postDelayed
答案:B
使用 rememberUpdatedState 後,要在 LaunchedEffect 中取得最新 Lambda,應該?
A. 直接呼叫原來的 lambda 變數
B. 透過 updatedLambda.value()
C. 使用 by 委託取得 updatedLambda,再呼叫它
D. 不可能取得最新值
答案:C
若使用 Animatable 搭配 LaunchedEffect 實作數字動畫,應該把哪個值作為 key?
A. Animatable 物件本身
B. 當前計數器(counter)的 State 值
C. rememberCoroutineScope
D. viewModelScope
答案:B
LaunchedEffect 區塊會在何種情況被取消?
A. 當 key 發生變化
B. 當螢幕熄滅
C. 當其他 Composable 產生副作用
D. 永遠不會被取消
答案:A
相較於 rememberCoroutineScope,viewModelScope 更適合長時間任務,原因為?
A. viewModelScope 使用多執行緒池
B. 其生命週期與 ViewModel 對應,較不易被 UI 銷毀
C. viewModelScope 自動重試失敗任務
D. Compose 強制要求
答案:B
若在 Composable 中直接 collect Flow,可能造成下列何者?
A. Flow 只會收集一次
B. 當前協程會阻塞主執行緒
C. 每次重組皆重啟收集,導致重複或洩漏
D. Flow 會自動轉為 StateFlow
答案:C
若想保證 LaunchedEffect 區塊只在入場時收集一次 Flow,key 應該如何設置?
A. 不傳 key
B. 傳入 MutableState 物件
C. 傳入固定值 true 或 Unit
D. 傳入當前時間戳
答案:C
在 Jetpack Compose 中,哪一種情況會觸發 recomposition?
A. 按下手機電源鍵
B. State 或 MutableState 的值改變
C. 裝置連線到 Wi‑Fi
D. 從背景回到前景
答案:B
LaunchedEffect 本身是什麼?
A. 一個不可重用的類別
B. 一個 composable 函式,必須在 Composable 範圍內使用
C. 一個 Android Service
D. 一個 View 類別
答案:B
在幾種 effect handler 中,下列哪個被視為最常使用?
A. DisposableEffect
B. LaunchedEffect
C. SideEffect
D. ProduceState
答案:B
若要避免重組導致重複執行網路呼叫,應該使用哪個 effect handler 包裹?
A. LaunchedEffect
B. rememberUpdatedState
C. SideEffect
D. rememberCoroutineScope
答案:A
透過 rememberCoroutineScope 啟動的協程,在 Composable 離開 Composition 時會?
A. 自動取消
B. 持續運行到應用結束
C. 轉移至 Service
D. 暫停並在回來時繼續
答案:A
LaunchedEffect 可以放在下列何處?
A. 任何 Kotlin 檔案
B. Service onCreate
C. 只能置於 Composable 函式內
D. BroadcastReceiver
答案:C
需要在 effect 區塊內取得最新 lambda 實例,但又不想重新創建協程,應該採用?
A. key = lambda
B. rememberUpdatedState
C. GlobalScope.launch
D. DisposableEffect
答案:B
若 LaunchedEffect 的 key 不含可能變動的 lambda,而 lambda 本身卻被替換,會導致?
A. 協程自動更新 lambda
B. 協程持續使用舊的 lambda,邏輯錯誤
C. 編譯失敗
D. lambda 被 GC 回收
答案:B
在 UI 回呼(如 onClick)中正確啟動 coroutine 的方式是哪一個?
A. viewModelScope.launch
B. rememberCoroutineScope().launch
C. LaunchedEffect(Unit) { … }
D. runBlocking { … }
答案:B
不當的副作用實作可能產生的後果包括?
A. 記憶體洩漏與重複網路請求
B. 編譯速度變慢
C. APK 體積增大
D. 減少程式碼行數
答案:A
LaunchedEffect 與 rememberCoroutineScope 的主要差異為何?
A. 前者屬於 Composable 區塊,後者回傳 Scope 供回呼使用
B. 前者只能用於回呼,後者只能用於 Effect
C. 兩者完全相同
D. rememberCoroutineScope 會自動重試協程
答案:A
在 DisposableEffect 中,關於 onDispose 區塊的敘述何者正確?
A. 必須與 rememberCoroutineScope 結合使用
B. 僅在 key 為 null 時才需要實作
C. 用於在 Composable 離開 Composition 時釋放資源
D. 僅能呼叫非同步(suspend)函式
答案:C
當 DisposableEffect 的 key 改變時,Compose 的行為為何?
A. 重新執行 effect 區塊,且先執行 onDispose
B. 直接取代舊區塊,不呼叫 onDispose
C. 什麼都不做
D. 僅在下一次重組時才移除舊區塊
答案:A
下列哪個情境最適合使用 DisposableEffect?
A. 每秒發射 UI 值
B. 建立並移除 LifecycleObserver
C. 快取複雜計算結果
D. 監聽 State 改變並轉為 Flow
答案:B
DisposableEffect 與 LaunchedEffect 的主要差異為何?
A. LaunchedEffect 可定義 onDispose,DisposableEffect 不行
B. DisposableEffect 支援清理機制,LaunchedEffect 不支援
C. 兩者皆不可傳入 key
D. LaunchedEffect 只能在 Activity 內使用
答案:B
若要在 ViewModel 層監聽 Lifecycle 而非 UI 層,應使用?
A. LaunchedEffect
B. DisposableEffect
C. LifecycleObserver 於 ViewModelScope
D. ProduceState
答案:C
SideEffect 會於哪個時機被呼叫?
A. 每次成功完成 recomposition 後
B. 每個畫面旋轉事件發生時
C. 組成剛開始時
D. 只有當 key 改變時
答案:A
SideEffect 的理想用途為?
A. 快取大量資料
B. 更新非 Compose 狀態或第三方 SDK 屬性
C. 處理複雜動畫
D. 監聽 Lifecycle
答案:B
SideEffect 區塊是否允許執行 suspend 函式?
A. 允許,因內部有 CoroutineScope
B. 不允許,只能執行同步程式碼
C. 允許,但僅限 IO coroutine
D. 允許,需搭配 rememberCoroutineScope
答案:B
如果需要將 Compose 的 State 轉換成 Flow,以便套用 Flow 運算子,應使用?
A. collectAsState
B. produceState
C. snapshotFlow
D. derivedStateOf
答案:C
snapshotFlow 與 collectAsState 的功能關係為?
A. 兩者皆將 Flow 轉為 State
B. snapshotFlow 將 State 轉為 Flow;collectAsState 將 Flow 轉為 State
C. 兩者皆將 State 轉為 Flow
D. snapshotFlow 僅支援 StateFlow
答案:B
snapshotFlow 產生的 Flow 具有下列哪項特性?
A. 永遠是熱流 (Hot)
B. 僅在有收集者時監聽 State 變更
C. 預設緩衝 100 個元素
D. 會自動重播前 5 個值
答案:B
在 snapshotFlow 中使用 distinctUntilChanged() 的主要目的為?
A. 避免重複發射相同值
B. 自動切換到 IO 執行緒
C. 加速重組流程
D. 將冷流轉為熱流
答案:A
produceState 的初始值指定方式為?
A. 於呼叫端指定 initialValue 參數
B. 在區塊內用 emit(0)
C. 於 CoroutineScope.launch 裡設定
D. 使用 remember 更新
答案:A
produceState 與 LaunchedEffect 皆可啟動 Coroutine;produceState 額外提供?
A. 清理機制
B. 直接回傳可觀察的 State 物件
C. 監聽 Lifecycle 事件
D. 轉換 State 為 Flow
答案:B
若要每秒更新 UI 上的倒數計時器,最佳做法為?
A. LaunchedEffect + State
B. DisposableEffect
C. produceState 回傳 State
D. SideEffect
答案:C
derivedStateOf 的核心作用是?
A. 將 State 轉為 Flow
B. 快取依賴其他 State 的計算結果
C. 提供 Lifecycle 清理點
D. 發射 State 至外部 SDK
答案:B
若 derivedStateOf 內部依賴的 State 未變動,但多個 Composable 讀取該值,Compose 會?
A. 每次讀取皆重新計算
B. 使用先前快取值,不重算
C. 重新啟動整個重組
D. 觸發 SideEffect
答案:B
在 derivedStateOf 區塊內執行昂貴計算可帶來何種效益?
A. 每次讀取都避免計算
B. 減少不必要的 recomposition 計算負擔
C. 自動轉換為 Lazy 計算
D. 讓 CoroutineScope 自動管理
答案:B
若 derivedStateOf 內僅讀取常數,而無任何可觀察 State,其計算會?
A. 每次重組都執行
B. 只執行一次並快取
C. 從不執行
D. 直到 onDispose 才執行
答案:B
若需要在 Composable 離開畫面時自動移除觀察者並取消協程,應選用?
A. GlobalScope.launch
B. DisposableEffect
C. SideEffect
D. snapshotFlow
答案:B
下面哪一個 effect handler 不支援傳入 key?
A. DisposableEffect
B. LaunchedEffect
C. SideEffect
D. produceState
答案:C
DisposableEffect 的 onDispose 區塊內適合執行何種操作?
A. 建立資料庫連線
B. 停止位置更新並移除回呼
C. 更新 UI 文本
D. 執行複雜計算並快取
答案:B
SideEffect 是否能保證在 recomposition 失敗時被呼叫?
A. 能
B. 無此保證
C. 只有在 key 改變時才保證
D. 取決於編譯器最佳化
答案:B
當 snapshotFlow 觀察的 State 連續快速變動時,Flow 會?
A. 丟棄中間值、只保留最新
B. 預設全部發射,除非進一步操作
C. 自動壓縮成集合
D. 停止發射
答案:B
若 snapshotFlow 內部引用的 State 被移除 Composition,Flow 會?
A. 永遠持續發射
B. 自動完成 (complete)
C. 轉為熱流
D. 崩潰並拋出例外
答案:B
produceState 區塊若需要釋放資源,應如何處理?
A. 直接呼叫 cancel()
B. 在區塊結尾使用 awaitClose
C. 透過 DisposableEffect 包裹並於 onDispose 清理
D. 不可能清理
答案:C
何時應避免使用 SideEffect?
A. 僅需一次性初始化
B. 每次 recomposition 都必須同步外部物件
C. 需要使用 suspend 函式、長時間作業
D. 同步非 Compose 狀態
答案:C
對 derivedStateOf 使用 by 委託 (val foo by derivedStateOf { … }) 的好處為?
A. 自動快取並提供可讀屬性
B. 強制執行在 IO 執行緒
C. 隱藏 StateFlow 細節
D. 能自動清理
答案:A
DisposableEffect 的 key 採用 LifecycleOwner 的意義在於?
A. 每次 Activity 旋轉都執行 onDispose/onCreate
B. 保證 Observer 與正確的 Lifecycle 綁定
C. 只要畫面亮起就會重設
D. 避免產生多餘的 Snapshot
答案:B
如果必須同時利用 Flow 運算子與 Compose State,以下組合最佳為?
A. collectAsState → snapshotFlow → SideEffect
B. snapshotFlow → Flow 運算子 → collectAsState
C. derivedStateOf → DisposableEffect → GlobalScope
D. produceState → DisposableEffect → snapshotFlow
答案:B
rememberCoroutineScope
是一個用於創建協程(Coroutine)作用域的函數。它允許在組件(composable)中創建協程,並在該組件生命週期結束時取消所有未完成的協程。這有助於避免在組件重新構建時發起多個重複的協程。rememberCoroutineScope
創建的作用域會與組件的生命週期綁定,當組件不再可見或結束時,其內部的協程也會被取消。onClick
、onTextChanged
等在用戶操作或界面事件觸發時調用的函數。在這些回調函數中使用 rememberCoroutineScope
是安全的,因為它們不與組件的重新構建相關聯,不會導致多次不必要的協程啟動。rememberCoroutineScope
。rememberUpdatedState
作為一種委託方式來管理狀態。onDispose
函數來清理資源,特別適用於需要在 Compose 組件結束時進行清理的場景,例如移除生命周期監聽器。produceState
函數。該函數的目的是生成隨時間變化的某種狀態,類似於Flow。produceState
函數提供了一個協程範疇,可以在其中調用掛起函數(如delay
)。map
、filter
、distinctUntilChanged
等。