### 什麼是 Bound Service * 一種允許其他應用元件(如 Activity)與之綁定並進行互動的 Android Service。 * 和 `startService()` 不同,Bound Service 提供與 client 的雙向通訊。 * 通常用於提供長時間運作但需和 UI 互動的後台功能(如播放音樂、下載管理等)。 * 生命周期與綁定它的元件綁在一起,當沒有元件綁定時會自動銷毀。 --- ### Service 類別實作(MyBoundService) ![image](https://hackmd.io/_uploads/SkrYTTwUgl.png) * 繼承自 `Service`,提供綁定式服務。 * 使用 inner class `LocalBinder` 回傳 service 實例。 * `performTask()` 為可供綁定端呼叫的公開函式。 * `onBind()` 回傳 binder,供外部綁定使用。 * Service 未標示為 exported,僅限本 app 使用。 --- ### 為什麼使用 inner class `LocalBinder` 回傳 service 實例 * inner class 可以直接存取外部 `Service` 類別的成員,簡化實作。 * 提供 `getService()` 方法讓 client 取得 `Service` 實體,進而存取其公開函式。 * 避免使用 IPC,因為本應用內部使用,效能更高且簡單。 * 封裝綁定細節,符合內聚與封裝設計原則。 --- ### AndroidManifest.xml 註冊 ![image](https://hackmd.io/_uploads/S1wspTwIgl.png) * `<service>` 元素指定 `MyBoundService`。 * 設定 `android:exported="false"` 限制外部元件存取。 * `MainActivity` 設定為啟動 Activity,含 `MAIN` 與 `LAUNCHER` intent filter。 --- ### Compose 畫面中初始化綁定狀態 ![image](https://hackmd.io/_uploads/BkCRT6PIll.png) * 使用 `LocalContext.current` 取得 context。 * 使用 `rememberSaveable` 管理 `serviceBound` 與 `service` 狀態。 * 透過 `remember` 宣告 `ServiceConnection`。 * `onServiceConnected` 中轉型 binder 並取得 service 實例。 * `onServiceDisconnected` 將 service 設為 null 並更新綁定狀態。 --- ### Compose 中啟動與解除綁定行為 ![image](https://hackmd.io/_uploads/rkWG06DLxe.png) * `LaunchedEffect(Unit)` 中呼叫 `bindService()` 啟動綁定。 * 使用 `Context.BIND_AUTO_CREATE` 自動建立連線。 * `DisposableEffect(Unit)` 中處理畫面銷毀時解除綁定邏輯。 * 僅當 `serviceBound = true` 時才呼叫 `unbindService()`。 --- ### Compose 畫面中呼叫 Service 方法 * 使用 `Column` 進行畫面排列。 * 判斷 `service` 不為 null 時呼叫 `performTask()`。 * 使用 `Text()` 顯示從 service 傳回的結果字串。