Daily Digest

每日新聞摘要

2026年08月21日

今日總結

內容會跟隨語言切換。

📝 今日焦點 - Android 相機競爭與相機總開關可讓背景錄影失敗,重試不保證恢復,專機專用最穩。 - KMP/Compose 在 iOS 匯出卡死、LazyColumn 只在正式版崩潰,顯示跨平台與並發副作用風險高。 🔧 效能最佳化 - 偵測並移除硬編碼機密,結合掃描、歷史重寫與後端代理,降低外洩與攻擊面。 🏗 架構設計 - 以 API/實作模組分享功能型 composable,清楚切分契約與細節,提升模組化。 - iOS 專屬流程應依是否可共用、回呼、記憶體與 UI 判斷,必要時改用 Swift。 ✅ 測試與品質 - Compose production 當機與相機失敗案例都提醒:需補強並發測試與失效回復驗證。

01

Can Two Apps Use the Same Android Camera at Once? How the OS Picks a Winner - and Why a 24/7 Recording Is the One That Loses

Dev.to Kotlin 作者:Super Funicular 發布:08-21 07:19

兩個 Android App 能同時使用同一個相機嗎?系統如何決定勝負,以及為何 24/7 錄影最常輸

Android 以優先權仲裁相機,而優先權跟隨使用者目前看到的畫面;輸掉的一方只會被通知,不會被詢問。

重點摘要

Android 不支援兩個第三方 App 同時持有同一顆相機。
前景 App 具有較高優先權,會把背景錄影程式擠下線。
相機可能以多種方式被拿走,甚至只會得到空白畫面而沒有錯誤。

Android 不允許兩個第三方 App 同時使用同一個相機,系統會依優先權決定誰能取得裝置,而前景中的應用通常會勝出,導致背景錄影程式收到 onDisconnected。文章詳細說明 onError 與 onDisconnected 的差異、相機被奪走的五種錯誤狀況,以及 Android 12 之後的全裝置相機開關可能讓畫面變成空白但不觸發錯誤。文中也說明實際可行的恢復方式有限,重試只是一場重新競爭,而不是排隊等候,因此把手機當監視器時最好專機專用。

02

Where Kotlin Stops and Swift Starts in a Kotlin Multiplatform App

Dev.to Kotlin 作者:Kanon Fujita 發布:08-21 14:18

在 Kotlin Multiplatform 應用中,何時該停在 Kotlin、何時該交給 Swift

我真正該問的不是怎麼修,而是這段程式為什麼會寫在 Kotlin 裡。

重點摘要

iOS 影片匯出因 completion handler 未觸發而卡死,導致 coroutine 無限等待。
作者整理出四個判斷問題,決定 iOS 功能該留在 Kotlin 還是改用 Swift。
可同步完成的 AVFoundation 設定留在 Kotlin;回呼、手動釋放記憶體與 UI 元件則交給 Swift。

作者以 Afterfade 為例,說明自己如何用 Kotlin Multiplatform 與 Compose Multiplatform 開發 Android 與 iOS,卻在 iOS 影片匯出時遇到卡死問題。原本以 suspendCancellableCoroutine 包裝 AVAssetExportSession 的 completion handler,卻在某些情況下永遠收不到回呼,改 dispatcher 或加 timeout 也無法真正解決。作者因此反思:這段程式其實無法與 Android 共用,只是把 iOS 專屬邏輯包在 Kotlin 外殼裡。之後他提出四個判斷準則,依序檢查是否能共用、是否依賴回呼、是否需要手動釋放記憶體、是否屬於 UI 元件,並據此把多數 iOS 專屬工作移到 Swift,而可同步執行的 AVFoundation 設定仍保留在 Kotlin。

03

[REDACTED] — How to keep your mobile app’s secrets, a secret!

ProAndroidDev 作者:Ed Holloway-George 發布:08-21 13:58

[REDACTED]——如何讓行動應用程式的機密保持機密

身為行動開發者,我們經常會遇到需要讀取或儲存機密的情境。

重點摘要

使用 betterleaks 或 gitleaks 掃描程式碼與 git 歷史中的機密。
透過 BFG Repo Cleaner 或 git-filter-repo 重寫歷史並移除外洩內容。
盡量以後端代理與金鑰限制降低 App 內保存機密的風險。

本文說明為何在行動應用中硬編碼機密是重大的資安與商業風險,尤其在 AI 能協助攻擊者更有效找出外洩內容的時代更需重視。作者建議先用 betterleaks 或 gitleaks 掃描程式碼與版本歷史,再以 BFG Repo Cleaner 或 git-filter-repo 重寫歷史,清除曾經提交的敏感值。接著可將機密移出原始碼,搭配 CI 檢查與程式碼審查防止再度混入,並在可行時對 API 金鑰做來源與權限限制。最終目標是透過後端代理,盡可能讓 App 不再直接持有機密。

04

Sharing Feature-Based Composables Through API Modules

Medium Kotlin 作者:Humbet Humbetov 發布:08-21 08:21

透過 API 模組分享以功能為基礎的 Composable

API 與實作模組是分享資料與領域契約的常見方式。

重點摘要

API 模組與實作模組可分離契約與實作。
Repository 介面或 use case 可放在 API 模組中。
此模式也可用於分享功能導向的 composable。

本文介紹如何透過 API 與實作模組,乾淨地分享以功能為基礎的 composable。作者指出,這種做法在資料與領域契約的共享上已相當常見,例如將 repository 介面或 use case 放在 API 模組,而真正的實作則保留在另一個模組中。相同概念也能延伸到 composable,讓團隊能對外提供功能層級的抽象,同時避免洩漏內部細節,進而讓依賴關係更清楚、模組化更完整。

05

The Optional<Keywords> That Encapsulate A Generic Nerd

Medium Kotlin 作者:Rajeev chachra 發布:08-21 12:02

包裹泛型書呆子的 Optional<Keywords>

這是我在 Medium 上的第一篇文章,因此用「Hello World」並透過「contract programming」作為開場是合理的。

重點摘要

作者表示這是他在 Medium 的第一篇文章。
文章以「Hello World」式的方式開場。
內文提及 contract programming 與 Kotlin 相關主題。

這篇 Medium 文章被作者定位為首篇發表,因此以輕鬆的「Hello World」方式開場。就目前可見內容來看,文章將這個開場與 contract programming 及 Kotlin 或泛型程式設計的概念連結,但原文片段已截斷,無法得知完整論述。整體而言,重點在於作者的自我介紹與帶有趣味性的技術引子,而非完整的技術分析。

06

Jetpack Compose LazyColumn Crash: “measure is called on a deactivated node” — Root Cause and Fix

Medium Kotlin 作者:Swaran Singh Aulakh 發布:08-21 13:41

Jetpack Compose LazyColumn 當機:〈measure is called on a deactivated node〉— 根因與修正

並發的 UI 更新與重複的副作用,如何在正式環境觸發 Compose 版面配置當機,以及最後如何修正。

重點摘要

並發的 UI 更新在正式環境引發版面配置當機。
重複的副作用是問題形成的一部分。
文章說明了根因分析與最終修正方式。

本文描述一個 Jetpack Compose 在正式環境中發生的 LazyColumn 當機,錯誤訊息為「measure is called on a deactivated node」。作者追查後指出,並發的 UI 更新加上重複觸發的副作用,讓 Compose 在版面配置測量時出現類似競態的問題。文章重點在於這個錯誤只在 production 出現,並說明如何找出根因,最後完成修正。

07

Flutter Meets Android Home Screen Widgets

Medium Kotlin 作者:Tom 發布:08-21 14:30

Flutter 與 Android 主畫面小工具的結合

一個能在應用程式重啟後仍然存在的資料邊界

重點摘要

探討 Flutter 與 Android 主畫面小工具的整合。
重點在於跨越應用程式重啟仍可保留的資料邊界。
目前提供的內容僅為 Medium 的極短摘要。

這篇文章〈Flutter Meets Android Home Screen Widgets〉從標題可知主題是 Flutter 與 Android 主畫面小工具的整合。依據目前提供的片段,文章強調一個能在應用程式重啟後仍然存在的資料邊界,暗示作者關注的是小工具與應用之間狀態傳遞或資料保存的設計方式。不過,現有內文只有非常簡短的摘要,無法得知完整實作或更多細節。