Daily Digest

每日新聞摘要

2026年09月13日

今日總結

內容會跟隨語言切換。

📝 今日焦點:本期涵蓋 Spring、Kotlin、Compose、Flow 與 Android 生態更新,核心共識是規格要貼近程式碼、版本與架構設計要可驗證、可維護。 🔧 效能最佳化:Cloudflare 以 DNS 快取優化省下 100 TB 記憶體;Compose 透過穩定型別與記憶體分析大幅降配置,APK 體積案例亦顯示可望從百 MB 壓到 17.76 MB。 🏗 架構設計:DI 驅動的啟動編排、樣板專案多模組化、版本化加密層與隱私優先的本機解析,讓初始化、遷移與資料治理更可控。 ✅ 測試與品質:取消上傳、Flow 融合、Stack Trace Recovery 與憑證釘選更新都指出,只有測試、重驗證與安全輪替到位,才不會把錯誤包成成功。 🚀 語言演進:Kotlin 與 Java 的選型回到場景判斷;Kotlin Flow、Channel、Explicit Backing Fields 與 KMP/tvOS 相關演進,持續擴大 JVM 與跨平台能力。

01

Java Weekly, Issue 663

Baeldung 作者:baeldung 發布:09-13 11:00

Java Weekly,第 663 期

從規格驅動開發走向 Java 專案中的活規格。

重點摘要

Spring 與 Java 區彙整規格、工具與版本更新。
技術文章討論代理記憶、AI 評估與 JVM 除錯。
本週精選介紹 Cloudflare 透過 DNS 快取最佳化節省大量記憶體。
展開詳細摘要

本期彙整 Spring、Quarkus、Kotlin、Jetty、Vert.x、Elasticsearch 與 Micronaut 等 Java/JVM 相關文章,也收錄網路研討會與版本更新資訊。重點文章主張把規格更貼近程式碼,讓它們在系統演進時仍可測試、可維護。技術區則從 Werner Vogels 將代理記憶比擬為大腦談起,延伸到 AI 評估、代理除錯與情境工程等主題。本週精選則介紹 Cloudflare 如何藉由優化 1.1.1.1 的 DNS 快取,節省 100 TB 記憶體。

02

A "resolved" state that never resolves is just a renamed unknown

Dev.to Kotlin 作者:StareBrain 發布:09-13 09:24

一個永遠不會被解決的「已解決」狀態,只是換了名字的未知

如果 DENIED_UNRESOLVED 只是停在日誌裡的終態,那我並沒有消除不確定性,只是把它改了名字。

重點摘要

未解狀態必須靠持續重查與升級處理,不能只是一個標籤。
綁定參數的確認 token 可防止參數漂移,但無法防止世界狀態漂移。
這套模型同樣適用於本機寫入,不只外部 API。
展開詳細摘要

作者重新檢視三態執行模型:EXECUTED、DENIED_CONFIRMED 與 DENIED_UNRESOLVED,指出未解狀態只有在之後能被真正釐清時才有意義。若沒有週期性重查、證據到達時的狀態晉升,以及逾期後的升級通知,未解只會變成另一種不確定。文中也補上第二個缺口:確認 token 能避免收件人或訊息等參數漂移,卻無法防止行程被占用、權限改變等世界漂移。結論是,token 綁定與獨立重驗證都不可少,且本機寫入同樣需要可回讀的誠實檢查。

03

Parsing bank statements in memory: keep the fields, store nothing else

Dev.to Kotlin 作者:Royal Simpson Pinto 發布:09-13 09:30

在記憶體中解析銀行對帳單:只保留欄位,不存其他內容

這套隱私承諾不是一份要你相信的政策,而是程式本身的實際形狀。

重點摘要

檔案只在記憶體中解析,之後立即丟棄,不寫入磁碟或伺服器。
CSV 匯入完全在裝置端執行,並具備格式檢查與大小限制。
收據 OCR 與商家分類都在本機完成,只保存確認過的交易欄位。
展開詳細摘要

PennyRush 的核心隱私設計,是把銀行對帳單與收據先讀入記憶體、解析後立刻丟棄,不寫入磁碟、物件儲存、日誌或分析系統。系統只保留金額、日期、商家、備註、類型與分類等結構化欄位。CSV 匯入完全在裝置端進行,並會檢查檔案類型、大小、行數、表頭與異常值。收據掃描則使用 ML Kit 的本機 OCR,商家擷取與分類採規則式處理。這種做法雖然少了部分自動化能力,但讓隱私保證直接由架構本身支撐。

04

One Flag, Two Checkpoints: How a Canceled Upload Reported Success

ProAndroidDev 作者:Vitaliy Gribko 發布:08-31 14:07

一個旗標、兩道檢查點:被取消的上傳如何回報成功

被取消的上傳之所以被判定為成功,是因為兩個無聲的失誤在錯誤時刻同時發生。

重點摘要

中斷只是請求,不是保證;若例外被吞掉,取消就會失效。
executor 從未呼叫 onCancel(),導致取消旗標一直是 false。
最終修補先設旗標,再在 task 內加上兩道檢查點。
展開詳細摘要

這篇文章剖析一個短影音 SDK 的取消上傳錯誤:使用者按下取消後,畫面先顯示處理中,之後卻被誤判為成功上傳,留下只有重新整理才會消失的幽靈項目。根因有兩處:executor 只中斷執行緒,卻沒有先設定取消旗標;而上傳函式庫在輪詢時吞掉了中斷例外,讓流程正常返回。由於路由只看旗標,task 最終走到成功分支。真正上線的修補很小,只是先設旗標,並在進度回呼與 upload() 返回後各做一次檢查。文章也說明為何測試沒抓到,以及較大的同步取消 API 最後被移除。

05

The Recompositions That Weren’t There!

ProAndroidDev 作者:Qamar A. Safadi 發布:09-03 16:59

那些其實沒被看見的重組

記憶體配置資料揭露了 Layout Inspector 對 Compose 重組的盲點。

重點摘要

Layout Inspector 低估了實際工作量,記憶體分析器才看出真相。
不穩定資料類別、列表、lambda 與缺少 key 造成額外重組與配置。
透過 @Immutable、ImmutableList、remember 與簡化元件結構改善表現。
展開詳細摘要

作者在分析一個看似平靜的 Compose 畫面時,發現 Layout Inspector 顯示的重組次數很少,但記憶體配置卻暴增。進一步追查後,他找到多個問題來源:未標註 @Immutable 的資料類別、使用 List 介面造成不穩定性、每次重組都重建的 annotated string、會連鎖傳遞的 lambda、lazy list 缺少 key,以及多餘的 wrapper composable。修正後,配置量大幅下降。文章強調,僅看重組計數容易誤判,應搭配記憶體配置分析,才能真正理解 Compose 在做什麼。

06

My Journey Making Compose Multiplatform Work on tvOS, and What I Learned

ProAndroidDev 作者:Sajid Ali 發布:09-09 01:13

我讓 Compose Multiplatform 在 tvOS 上運作的旅程,以及我的學習心得

這個系列講的是,這項需求最後如何讓我維護一個支援 tvOS 的 Compose Multiplatform 分支,以及我一路上的收穫。

重點摘要

為了在行動裝置、TV、桌面、iOS 與 tvOS 之間共享 UI,團隊選擇了 Compose Multiplatform。
SwiftUI 的焦點管理無法重現既有的 Android TV 行為,因此改為推進 Compose 的 tvOS 支援。
移植工作涵蓋 Gradle 外掛、runtime 模組,以及輸入、焦點與渲染等 tvOS 特有部分。
展開詳細摘要

這篇文章以高層次回顧一個串流應用團隊如何走到維護支援 tvOS 的 Compose Multiplatform 分支。作者說明專案先後經歷 Android Views、Jetpack Compose,到為了在 Android、桌面、iOS 與 tvOS 間共享 UI 而採用 Compose Multiplatform;原本打算用 SwiftUI 做 Apple TV 介面,但因焦點管理無法符合 Android TV 的行為而作罷。文章接著介紹 tvOS 與 iOS 的差異、Kotlin Multiplatform 目標所帶來的移植成本,並拆解 Gradle 外掛與 runtime 兩條修改路線。最後整理模組移植順序、uiKitMain 的共用設計,以及最困難的輸入、焦點、渲染與持續跟進上游變更。

07

Forget the “Setup Tax”: A Production-Ready Multi-Module Android Template

ProAndroidDev 作者:Shamil Gulmetov 發布:09-09 01:34

忘掉「設定稅」:可直接上線的多模組 Android 範本

這是一個乾淨、可投入生產的起始專案,將 NiA 最佳的架構模式抽離為獨立基礎。

重點摘要

採用以功能與層次劃分的多模組架構,分離核心、功能、建置邏輯與 lint
以 Kotlin Convention Plugins 集中管理 Gradle、Compose、flavor 與 coverage 設定
提供自訂 lint 規則、狀態與 Flow 輔助、設計系統 tokens,以及自動重新命名腳本
展開詳細摘要

本文介紹一個面向生產環境的 Android 範本,目標是消除開發新專案前繁瑣而重複的基礎設定。範本參考 Google 的 Now in Android,將架構拆成以功能為主的多模組結構,並用 Kotlin Convention Plugins 集中管理建置邏輯,同時以自訂 lint 規則約束架構與設計系統使用方式。它也提供可重用的 Flow/StateFlow 輔助工具、獨立的設計系統,以及以 Hilt 管理的 dispatcher 與 scope。為了加速導入,專案還附帶自動化腳本,可用單一指令完成套件與品牌名稱更新,降低樣板碼與設定失誤。

08

The Android Startup Pattern: A Lifecycle-Aware, Multi-Module Approach

ProAndroidDev 作者:Ehab Elwan 發布:09-13 05:31

Android 啟動模式:具備生命週期感知的多模組作法

以 DI 為核心的乾淨架構,用來處理冷啟動、背景喚醒與現代 Android App 的隱私合規。

重點摘要

透過多重繫結匯集各模組的啟動任務,由主應用統一排程。
依冷啟動、前景與登入狀態拆分任務,並以相應生命週期驅動。
任務需具備冪等、主執行緒安全與同意狀態感知,才能安全重試與符合隱私要求。
展開詳細摘要

本文提出一種以 DI 驅動的 Android 啟動模式,用多重繫結把各功能模組的啟動任務匯入同一集合,再由分階段的 orchestrator 依冷啟動、前景與使用者登入狀態執行。作者強調任務必須冪等、主執行緒安全,並以一致的錯誤處理機制區分致命與非致命失敗,讓重試不會重複破壞已完成的工作。文中也說明 Jetpack App Startup 適合處理原生框架初始化,但不適合依賴 DI 或使用者同意的業務邏輯。最後建議 UI 以生命週期感知方式觀察啟動狀態,並讓畫面資料延遲載入,以降低閃爍、耗電與測試複雜度。

09

The “Downcast Trap” in Kotlin’s Explicit Backing Fields

ProAndroidDev 作者:Ehab Elwan 發布:09-13 05:31

Kotlin 明確後備欄位中的「下轉型陷阱」

明確後備欄位讓程式碼更簡潔,但它把實體包裝邊界換成了單純的型別限制。

重點摘要

舊作法以 .asStateFlow() 建立防護性包裝物件。
明確後備欄位省去包裝,但仍依賴向上轉型隱藏可變性。
若外部做惡意下轉型,內部狀態仍可能被直接修改。
展開詳細摘要

本文比較 Kotlin 傳統的雙屬性封裝與明確後備欄位。舊作法以私有的 MutableStateFlow 搭配公開的 StateFlow 包裝,雖然多一點配置成本,卻能提供明確的架構邊界。明確後備欄位省去包裝物件、寫法更簡潔,但底層物件本質上仍是可變的,因此外部若刻意下轉型成 MutableStateFlow,便可能繞過原本的封裝直接改動內部狀態。作者認為多數應用程式團隊可接受這種取捨,真正該注意的是公開 API 或 SDK 場景,這時保守包裝仍較安全。

10

I Counted Every Hidden Channel Kotlin Flow Creates — Most Devs Are Wrong About Which Operators Are…

ProAndroidDev 作者:Majidshahbaz 發布:09-13 05:43

我逐一計算 Kotlin Flow 產生的隱藏 Channel——多數人都誤解了哪些運算子會破壞融合

buffer() 和 flowOn() 的確會融合,但只要中間插入一般運算子,這個機制就會被打斷。

重點摘要

相鄰的 channelFlow、flowOn、buffer、produceIn 會透過 FusibleFlow 融合成單一 channel。
map()、catch()、onEach()、distinctUntilChanged() 都會破壞融合;conflate() 仍可保持融合。
融合被打斷後,會多出包裝物件、額外 coroutine 與更多 dispatcher 跳轉。
展開詳細摘要

本文驗證一個常見的 Kotlin Flow 說法:buffer() 與 flowOn() 會融合成單一 channel。作者不靠口耳相傳,而是透過反射、coroutine debug dump 與自訂 dispatcher 直接量測執行期行為。結果顯示,FusibleFlow 只會在相鄰的可融合運算子之間生效;一旦中間插入 map()、catch()、onEach() 或 distinctUntilChanged(),融合就會中斷,進而增加包裝層數、coroutine 數量與 thread hop 次數。相對地,conflate() 因為內部等同於 buffer() 的實作而能維持融合。文章提醒,在高吞吐情境下,應把可融合運算子盡量放在一起,別把看似簡單的轉換誤當成免費。

11

How We Cut Our Android App Size by 82%: From 100+ MB to 17.76 MB

Medium Kotlin 作者:Mahabub Karim 發布:09-13 08:21

我們如何將 Android App 大小縮減 82%:從 100 多 MB 降到 17.76 MB

一篇深入解析 APK 分析、R8、原生依賴、ABI 重複與 Compose Multiplatform 的實作文章。

重點摘要

透過 APK 分析找出主要的體積來源。
文章討論 R8、原生依賴與 ABI 重複問題。
Compose Multiplatform 也是優化討論的一部分。
展開詳細摘要

本文描述一個 Android App 將體積縮減 82% 的實務案例,從 100 多 MB 降至 17.76 MB。內容聚焦於 APK 分析,以及常見的檔案膨脹來源,例如 R8、原生依賴、ABI 重複與 Compose Multiplatform。就目前可見的文字來看,這是一篇偏技術實作的深度拆解,重點在於找出體積膨脹的原因並逐步加以處理。

12

From One Encryption Scheme to Many: Designing a Versioned Encryption Layer on Android

Medium Kotlin 作者:Jevi Saputra 發布:09-13 08:26

從單一加密方案到多種方案:在 Android 上設計版本化加密層

在 Android 上設計版本化加密層,以支援多種方案、維持向後相容,並讓遷移更安全。

重點摘要

支援多種加密方案
維持向後相容性
降低版本遷移風險
展開詳細摘要

本文介紹如何在 Android 上設計一個版本化加密層,讓應用程式能隨時間支援多種加密方案,而不必將所有資料綁定在單一做法上。這種設計的重點是保留向後相容性,並讓加密機制的切換與遷移更安全。由於原文僅提供摘要,未包含實作細節、效能數據或具體 Kotlin 實作內容。

13

Certificate Pinning in 2026: Rotating Pins Without Bricking Your App

Medium Kotlin 作者:Alim Reshitov 發布:09-13 08:41

2026 年的憑證釘選:如何輪替釘選而不讓應用程式失效

Network Security Config、OkHttp,以及多數釘選教學不會提到的輪替緩衝期

重點摘要

聚焦 2026 年的憑證釘選做法
重點在於輪替釘選而不讓 App 壞掉
提到 Network Security Config 與 OkHttp
展開詳細摘要

本文以 2026 年的憑證釘選為主題,強調多數教學常忽略的一點:如何在更新釘選時避免把應用程式弄壞。文章提到 Android 上相關的 Network Security Config 與 OkHttp,並指出釘選不能只做一次就結束,而需要預留輪替緩衝期,才能在調整憑證時維持應用程式連線與可用性。

14

Make coroutine stack traces great (and informative) again

Medium Kotlin 作者:Roman Andrushchenko 發布:09-13 10:57

讓 coroutine 堆疊追蹤再次變得優秀且具資訊性

Android 預設關閉 stack trace recovery。

重點摘要

Android 上的 stack trace recovery 預設為關閉。
文章說明如何將其開啟。
也提醒幾個可能悄悄讓它失效的陷阱。
展開詳細摘要

本文聚焦於 Android 上的 coroutine stack trace recovery。作者指出這項功能預設是關閉的,並說明如何將其啟用,讓 coroutine 發生錯誤時更容易追查問題。同時也提醒讀者注意一些看似不起眼的陷阱,因為它們可能在不知不覺中讓 stack trace recovery 失效,降低除錯時可取得的資訊量。

15

JetImagePicker: Effortless Image Picking in Jetpack Compose (With Zero Permission Worries)…

Medium Kotlin 作者:Nyerhovwo Adjekughene (Nerojust) 發布:09-13 13:35

JetImagePicker:在 Jetpack Compose 中輕鬆挑選圖片

本文介紹 JetImagePicker v2.0.0+,相較於 v1 有明顯演進,特別是權限處理的大幅改善。

重點摘要

涵蓋 JetImagePicker v2.0.0+
相較於 v1,函式庫已有明顯演進
權限處理獲得大幅改善
展開詳細摘要

本文介紹 JetImagePicker v2.0.0+,並指出這個函式庫自 v1 以來已有明顯演進。內容重點放在權限處理的改進,說明新版更著重於降低使用時的權限疑慮,提供在 Jetpack Compose 中更順暢的圖片挑選體驗。摘要可確認的資訊僅限於版本範圍與權限改善,未提供其他實作細節。

16

Kotlin vs Java in 2026: A 17-Year Java Developer’s Honest Take

Medium Kotlin 作者:Anupam Sinha 發布:09-13 14:57

2026 年的 Kotlin 與 Java:一位擁有 17 年經驗的 Java 開發者的誠實看法

以務實角度比較兩者真正各自擅長之處、Java 追上的地方,以及該如何選擇。

重點摘要

以務實角度比較 Kotlin 與 Java
聚焦兩種語言各自真正的優勢
也檢視 Java 已追上的部分與選擇方式
展開詳細摘要

本文以一位擁有 17 年 Java 經驗的開發者視角,對 2026 年的 Kotlin 與 Java 做務實、不中立偏頗的比較。作者不是要替任一語言站台,而是想說明兩者各自真正擅長的場景、Java 已經補齊的差距,以及開發者應如何依需求做選擇。由於摘錄內容未提供具體技術細節、基準測試或功能結論,因此可將這篇文章理解為一篇關於語言選擇的平衡觀點,而非效能定論。

17

I Counted Every Hidden Channel Kotlin Flow Creates — Most Devs Are Wrong About Which Operators Are…

Medium Kotlin 作者:Majidshahbaz 發布:09-13 05:43

我統計了 Kotlin Flow 產生的每個隱藏通道——多數開發者都誤判了哪些操作符會……

buffer() 和 flowOn() 在串接時,理應融合成一個通道。

重點摘要

作者檢視 Kotlin Flow 操作符所建立的隱藏通道。
buffer() 與 flowOn() 串接時,預期會融合成單一通道。
實驗中發現四個看似無害的情況,挑戰了常見認知。
展開詳細摘要

這篇文章探討 Kotlin Flow 會產生多少隱藏通道,並質疑大家對操作符行為的既有印象。作者先驗證 buffer() 和 flowOn() 串接時是否真的會融合成單一通道,再透過程式實作觀察實際結果。研究過程中又發現四個看似無害的情況,顯示許多開發者可能誤解了哪些操作符會建立通道,以及它們之間的互動方式。

18

Kotlin Weekly #528

Kotlin Weekly 作者: 發布:09-13 04:29

Kotlin Weekly #528

JetBrains 已釋出 Kotlin 2.4.20,本期也整理了 Compose、Ktor、AI 工具、Android 與新函式庫等多項內容。

重點摘要

JetBrains 已發布 Kotlin 2.4.20。
Shopify 表示行動端將回到 Swift 與 Kotlin,淡出 React Native。
本期收錄 Compose、Ktor、RevenueCat、Google Gen AI SDK for Kotlin、Android、影片與新函式庫。
展開詳細摘要

Kotlin Weekly #528(2026 年 9 月 13 日)整理了 Kotlin 生態系的最新消息、文章、影片與函式庫。焦點新聞包括 JetBrains 發布 Kotlin 2.4.20,以及 Shopify 在 AI 時代將行動開發從 React Native 轉回 Swift 與 Kotlin。文章部分涵蓋 Compose Desktop Native、以 Ktor 與 Exposed 建構 JWT 使用者管理、讓 Compose Web 離線運作、在 Kotlin Multiplatform 中整合 RevenueCat,以及全新的 Google Gen AI SDK for Kotlin。另有 Android 支付牆動畫、演講影片與 ARTEMIS、Library Insight 等新工具介紹。