Daily Digest

每日新聞摘要

2026年04月04日

今日總結

內容會跟隨語言切換。

📝 AndroidAppLockscreen 與 TheActivity 提供一行整合的鎖屏顯示與權限/結果處理方案,並整理 let/run/with/apply/also 用法以減少樣板並提升可讀性。 🔧 深入解析 Compose 插槽表與 gap buffer 如何限縮重組與重用 slot,以只更新必要 UI 並提升除錯與效能可觀察性。 🏗 協程易隱藏控制與生命週期邊界,建議以 ViewModel 搭配 SharedFlow/StateFlow 取代巢狀 callback,並以型別安全旗標(KMP/Swift)降低釋出風險。 ✅ 對 BLE 與 GATT 133,建議採 WorkManager+PendingIntent 結合短暫 Foreground 執行,實作明確狀態機與嚴格資源清理以提升穩定性。

01

Turn Any Android App Into a Lock Screen Widget — Here's How

Dev.to Kotlin 作者:Alex Devson 發布:04-04 07:43

將任何 Android 應用變成鎖定畫面小工具 — 操作教學

只需一行程式碼即可在鎖定畫面顯示任意 Activity,無需 root 或繁複設定。

重點摘要

可在鎖定畫面直接顯示任意 Activity
在 Activity 的 onCreate 呼叫 LockscreenHelper.init(this) 即可
不需 root、輕量且附範例與文件

AndroidAppLockscreen 是一個開源函式庫,可在 Android 鎖定畫面直接顯示任意 Activity,提供類似互動小工具的體驗且不需 root。整合非常簡單:加入 implementation 'p32929:AndroidAppLockscreen:LATEST_VERSION' 並在 Activity 的 onCreate 呼叫 LockscreenHelper.init(this),即可在鎖定畫面呈現該 Activity。常見應用包括鎖屏音樂控制、鬧鐘/計時器、新聞摘要、快速回覆介面與儀表板小工具。開發者喜歡它的零樣板程式碼、一行啟動、輕量體積、相容任何 Activity,並有完整範例與文件。原始碼與說明可在 GitHub(github.com/p32929/AndroidAppLockscreen)找到,適合需維持鎖屏可見性的應用。

02

TheActivity — The Android Library That Makes Permission Handling a One-Liner

Dev.to Kotlin 作者:Alex Devson 發布:04-04 10:37

TheActivity — 將 Android 權限處理簡化為一行的函式庫

TheActivity 是一個開源 Android 函式庫,將執行時權限處理濃縮為簡潔、可串接的一行呼叫。

重點摘要

一行請求權限並以回呼處理
啟動 Activity 取得結果無需請求代碼
輕量(約15KB)、零樣板、支援 Activity 與 Fragment

TheActivity 是一個開源的 Android 函式庫,將複雜的執行時權限處理濃縮為簡潔、可串接的一行呼叫。開發者不需覆寫 onActivityResult、管理請求代碼或手動檢查權限狀態,也能自動處理「不再詢問」等邊界情況。除了一行請求權限並以回呼處理允許/拒絕外,函式庫還支援無須請求代碼的啟動 Activity 取回結果、選取檔案/圖片/聯絡人,並可在 Activity 或 Fragment 中使用。體積輕量(約 15KB)、零樣板與零設定,已在生產環境中使用並處理各類 Android 邊界案例。專案於 GitHub(github.com/p32929/TheActivity)公開,若對你有幫助請幫忙點星。

03

Compose Slot Table Explained: I Read the Runtime Source, So You Don’t Have To

Medium Kotlin 作者:Nikhil Bajpai 發布:04-04 12:12

Compose Slot Table 解讀:我讀了 Runtime 原始碼,替你整理重點

間隙緩衝(gap buffers)、位置備忘(positional memoization)與重組(recomposition)——結合官方 Android 設計文件驗證,並附上實際程式碼與面試提示。

重點摘要

拆解 Compose 的 slot table 內部機制
說明 gap buffer 與位置備忘的角色
提供程式範例與面試重點提示

本文以閱讀 Compose runtime 原始碼為出發,並對照官方 Android 設計文件,系統性說明 slot table 的運作原理與實際應用。文章解釋了 gap buffer 如何在連續儲存中有效處理插入與刪除、位置備忘如何幫助追蹤與重用 composition slot,以及重組機制如何利用這些結構只更新必要的 UI 部分。作者以實際程式碼片段示範操作流程,點出常見誤區並給出面試相關的概念整理。目標是幫助工程師理解 Compose 的性能與除錯要點,減少直接閱讀大量 runtime 原始碼的負擔。

04

Swift, KMP: Type-Safe Feature Flags for Scaled Teams

Medium Kotlin 作者:Yeskendir Salgara 發布:04-04 13:00

Swift、KMP:為大型團隊設計型別安全的功能旗標

為開發者與使用者打造安全、可靠的功能旗標系統──以及為何 Firebase 的做法在規模擴張時不敷使用。

重點摘要

主張在 Swift 與 KMP 中實現型別安全的功能旗標。
強調系統需同時對開發者與最終使用者安全可靠。
指出 Firebase 的方法在團隊與使用量擴大時存在缺陷。

本文討論為大型團隊設計型別安全的功能旗標的重要性,聚焦 Swift 與 Kotlin Multiplatform(KMP)環境,主張透過型別與設計降低釋出風險並提升開發體驗。作者說明一套對開發者與使用者都可靠的旗標系統能避免設定或執行時錯誤,並維持跨平台的一致性;同時指出 Firebase 在規模化情境下的做法可能不足以應對這些挑戰,建議團隊採用能強化正確性與可維護性的模式與工具。

05

When Coroutines Break: Why Some Architectures Stay Predictable — and Others Fall Apart

Medium Kotlin 作者:Oliver Bozhinovski 發布:04-04 15:00

When Coroutines Break:為何有些架構保持可預測,而有些則崩潰

探討協程如何讓某些架構保持可預測性,同時使其他架構變得脆弱而失效。

重點摘要

協程讓非同步程式碼更簡潔,但可能引入隱性控制流程與隱藏的併發問題。
能將副作用封裝並明確界定責任的架構,與協程搭配時較為可預測。
不當使用協程會分散狀態與時序假設,導致難以除錯的崩潰。

Oliver Bozhinovski 在〈When Coroutines Break〉一文中討論協程對 Android 應用架構可預測性的影響。作者指出,協程雖然能簡化非同步程式,但也可能帶來隱含控制流程、隱藏的併發行為與生命週期耦合,讓系統行為難以推理。文章比較能將副作用封裝、明確責任與作用域的穩定架構,與允許協程跨界操作、散佈狀態與時序假設而變得脆弱的架構,並說明常見陷阱與權衡。作者建議採用限制副作用、明確擁有權與維持可觀察性的設計模式,使協程使用既高效又可維護。

06

Why I Stopped Using Callbacks in Android and Switched to Flow + ViewModel Events

Dev.to Kotlin 作者:Baharudin Maulana 發布:04-04 02:19

為什麼我不再在 Android 使用 Callback,而改用 Flow + ViewModel Events

在維護生產環境的 POS 應用時,巢狀回呼導致難以追蹤的生命週期與除錯問題,因此我改用 Flow 與 ViewModel 事件。

重點摘要

回呼會造成生命周期盲點、競態與難以測試的樣板程式
用 sealed class + SharedFlow 傳一次性事件,StateFlow 保存持久 UI 狀態
畫面端須在 viewLifecycleOwner.lifecycleScope 的 repeatOnLifecycle 中收集

作者在維護生產用 POS Android 應用時,因巢狀 callback 引發生命週期錯誤、競態條件與難以測試的代碼,決定改以 ViewModel 發出以 sealed class 表示的事件,使用 MutableSharedFlow/SharedFlow 傳遞一次性事件,並以 StateFlow 保存持久 UI 狀態;畫面端在 viewLifecycleOwner.lifecycleScope 裡以 repeatOnLifecycle 收集事件。此模式避免在 Activity/Fragment 銷毀後仍觸發事件、降低競態、讓測試與除錯更乾淨。注意事項包括:別在 repeatOnLifecycle 外收集、不要為事件流設 replay=1、避免用 tryEmit、Fragment 要用 viewLifecycleOwner。遷移後團隊減少生命週期崩潰、除錯更快、測試更簡潔。

07

Beyond the Foreground Service: Reliable Background BLE Connection Management on Android 12+

Dev.to Kotlin 作者:Ble Advertiser 發布:04-04 05:22

超越長駐 ForegroundService:在 Android 12+ 下可靠的背景 BLE 連線管理

透過 WorkManager、在 connectGatt 傳入 PendingIntent 的系統層 GATT 回調,以及短暫的 ForegroundService 結合,能在 app 程序死亡或重啟後仍維持連線。

重點摘要

以 WorkManager 排程與重試,讓連線嘗試能跨程序死亡與重開機持續執行
傳入 PendingIntent 至 connectGatt,系統會在應用進程不存在時仍送達 GATT 事件
僅在執行實際 GATT 操作時短暫提升為 ForegroundService,符合 API 31+ 規範且節省電量

Android 12 以後對背景執行與省電管理更嚴格,單靠長時間運行的 ForegroundService 無法穩定維持 BLE 連線。本文提出混合策略:以 WorkManager 排程與重試連線、在 connectGatt 傳入 PendingIntent 使系統在 app 程序死掉時也能送出 GATT 回調給 BroadcastReceiver、以及在需要實際執行 GATT 操作時短暫提升 Worker 為 ForegroundService。文章說明必要權限與 manifest 設定、示範 BroadcastReceiver 在斷線時排隊重連的做法,以及 BluetoothWorker 的實作要點(setForeground、CompletableDeferred、close GATT),並建議避免初次使用 autoConnect、維護連線狀態機與謹慎釋放資源,以提升連線韌性並遵守系統政策。

08

Demystifying Android BLE 'GATT Status 133': Common Causes and Robust Solutions for Connection Failures

Dev.to Kotlin 作者:Ble Advertiser 發布:04-04 05:33

破解 Android BLE 的 GATT Status 133:連線失敗的常見原因與穩健解法

GATT Status 133 是來自 Android 原生藍牙堆疊的通用錯誤碼,表示在 BLE 連線流程中發生未指定的連線失敗。

重點摘要

133 為原生藍牙堆疊(Bluedroid/Fluoride)回報的未指明連線錯誤。
對使用者主動連線請用 autoConnect=false,autoConnect=true 僅用於背景重連情境。
妥善管理 BluetoothGatt 生命週期、實作指數退避重試並維持單一操作的狀態機。

GATT Status 133 是 Android 原生藍牙子系統在建立或維持 BLE 連線時回報的通用錯誤,常於 CONNECTING 階段出現。可能成因包括無線干擾、週邊裝置不可用、BluetoothGatt 未正確關閉而佔用資源,或底層堆疊錯誤。建議採取的對策有:確認權限並請求執行時權限;對直接連線使用 connectGatt(..., autoConnect=false),僅在背景重連時使用 autoConnect=true;在 STATE_DISCONNECTED 後才呼叫 gatt.close() 並將參考設為 null;避免同時進行掃描與連線,實作明確的狀態機;在 callback 中把重作業轉到背景執行;必要時重啟藍牙或裝置以排查系統層問題。

09

Why I Stopped Using Callbacks in Android and Switched to Flow + ViewModel Events

Medium Kotlin 作者:Rudy DevKits 發布:04-04 02:02

為何我不再使用 Callback,而改用 Flow 與 ViewModel 事件

不是因為流行,而是為了保住我的理智。

重點摘要

Callback 帶來複雜性與心智負擔
使用 Kotlin Flow 可得更具宣告性的資料流
ViewModel 事件讓事件處理更符合生命週期、易於測試

作者說明他放棄在 Android 中頻繁使用 callback,轉而採用 Kotlin Flow 與 ViewModel 事件,原因並非趨勢,而是為了保護自己的理智。傳統 callback 常造成巢狀、難以追蹤的非同步流程與脆弱的狀態管理;改用 Flow 提供更宣告式的串流處理,並能與 coroutine 無縫整合,降低組合與推論非同步邏輯的難度。搭配 ViewModel 事件可建立符合生命週期的單次事件傳遞路徑,提升可預測性與測試性,整體減少心智負擔並促進程式碼維護。

10

Kotlin Scope Functions Explained (with Examples)

Medium Kotlin 作者:Suman Shil 發布:04-04 02:25

Kotlin 範圍函式解析(含範例)

若你使用過 Kotlin,應該會遇到五個範圍函式:let、run、with、apply 與 also。

重點摘要

介紹五個主要的 Kotlin 範圍函式
以範例說明各自的用法與差異
協助選擇適合的函式以簡化與增進可讀性

本文介紹 Kotlin 的五個 scope function:let、run、with、apply、also,並以範例說明其用途與差異。作者示範每個函式如何影響作用域物件與回傳值,並說明在物件初始化、處理 null 值與串接操作時,何時應選擇特定函式以提升可讀性與簡潔度。文章也提供實務建議與常見誤區說明,適合想釐清 scope function 行為並寫出更具表現力與低樣板碼 Kotlin 的開發者作為快速參考。