Daily Digest

每日新聞摘要

2026年08月30日

今日總結

內容會跟隨語言切換。

📝 今日焦點:本日聚焦 JSON null、協程取消、SafetyNet 退場與 smart cast,核心都是以可驗證邏輯取代假設,降低跨端與執行期風險。 🔧 效能最佳化:Muffle 以 GeofencingClient 取代高頻定位,透過 loitering delay 與緩衝機制兼顧省電與準確。 🏗 架構設計:ViewModel 解析回 AOSP 生命週期內部機制;Foster 以共享 UI 與 width class 快速支援平板導覽。 🚀 語言演進:Compose Multiplatform 1.12.0 帶來 AI 代理 MCP、Web 字型回退與桌面視窗 API,Kotlin 則持續強調可證明的 smart cast。

01

The Word "null" Is Not a Null: How JSON Nulls Turn Into Text on Android

Dev.to Kotlin 作者:Mahmut Gündüzalp 發布:08-30 10:39

「null」這個字不是空值:JSON null 在 Android 上如何變成文字

在 Android 上,optString 遇到 JSON null 不會回傳 "",而是回傳字串 "null"。

重點摘要

JSONObject.NULL 不是 Java null,會被 optString 轉成文字
JVM 上的 json.org 與 Android 的 org.json 行為可能不同
要同時修正 API 邊界與用戶端包裝函式

這篇文章指出,Android App 之所以在個人資料頁顯示「null」,是因為 JSONObject.optString() 遇到 JSON null 時,回傳的不是預設值,而是字面字串 "null"。作者說明 Android 的 org.json 使用 JSONObject.NULL 作為哨兵值,和 JVM 上的 json.org 實作不完全相同,因此桌面測試可能通過、裝置上卻失敗。問題源頭其實來自 PHP API:LEFT JOIN 與聚合函式在沒有資料時會產生 SQL NULL,序列化後變成 JSON null。解法必須雙管齊下:伺服器端在輸出邊界做正規化或以 COALESCE 補值,客戶端則不要直接呼叫 optString,而是包成帶 null 檢查的 helper。

02

Cooperative by Design: The Deep Mechanics of Kotlin Coroutine Cancellation

Medium Kotlin 作者:Android Expert 發布:08-30 08:24

以合作式設計看 Kotlin 協程取消:深入機制解析

為什麼 job.cancel() 不保證清理一定會發生,以及在正式版 Android App 中讓取消真正安全的做法。

重點摘要

Kotlin 協程的取消是合作式,而非立即中止。
呼叫 job.cancel() 不代表清理流程一定會自動執行。
在生產環境中需搭配正確模式,才能讓取消更安全。

本文指出,Kotlin 協程的取消機制是合作式設計,協程必須走到取消檢查點才會真正停止。因此,單純呼叫 job.cancel() 並不保證清理工作會立即或自動完成。文章聚焦於取消背後的實作邏輯,以及 Android 開發者在正式環境中應採用的安全模式,強調不能只依賴取消本身,而要以正確的流程與設計來避免風險。

03

SafetyNet Is Dead: Detecting Tampered Devices with Play Integrity API

Medium Kotlin 作者:Alim Reshitov 發布:08-30 08:26

SafetyNet 已死:使用 Play Integrity API 偵測被竄改的裝置

這是每個銀行 App 都被迫進行的遷移,而客戶端 token 只完成了一半工作。

重點摘要

銀行 App 被迫從 SafetyNet 轉移。
改以 Play Integrity API 偵測裝置是否被竄改。
客戶端 token 並不足以完成整個驗證流程。

本文聚焦於銀行 App 在 SafetyNet 退場後被迫進行的遷移,並以 Play Integrity API 作為偵測裝置是否遭竄改的替代方案。文章強調,取得客戶端 token 只是安全流程的一部分,真正的驗證仍需要更多後端或額外檢查,不能只依賴裝置端回傳的結果。這反映出金融應用在裝置完整性防護上的實務轉變。

04

Under the Hood of Android ViewModel: How State Survives Orientation Changes & Building Your Own…

Medium Kotlin 作者:Aslam Hossin 發布:08-30 15:02

深入 Android ViewModel:狀態如何在螢幕旋轉時保存,以及如何自行實作

一篇以原始碼為線索的深度解析,探討 Android 執行階段內部、AOSP ActivityThread 與 NonConfigurationInstances 機制。

重點摘要

說明 Android ViewModel 如何在設定變更中保留狀態
解析 Android 執行階段內部與 NonConfigurationInstances 機制
以教學角度示範如何理解並建立類似機制

本文以原始碼為線索,深入解析 Android 執行階段內部運作,說明 ViewModel 為何能在螢幕旋轉等設定變更時保留狀態。文章聚焦於 AOSP ActivityThread 與 NonConfigurationInstances 機制,將其視為狀態延續的關鍵,並在理解這些基礎後,進一步建立一個具教育意義的實作。整體內容適合想從底層理解 ViewModel 與 Android 生命週期關係的讀者。

05

Engineering Geofencing: Trading Battery for Precision in Android

Dev.to Kotlin 作者:Haseeb 發布:08-30 02:27

Android 地理圍欄工程:以電量換取精準度

我必須在電池續航與定位精準之間取捨,而 geofencing 提供了最佳平衡。

重點摘要

Muffle 旨在避免在會議、圖書館或宗教場合誤響,並自動切換音量模式。
作者選擇 GeofencingClient 取代持續輪詢,因為它更省電,但會帶來些許延遲。
為了提升可靠性,加入開機重註冊、GPS 漂移緩衝與 Wi‑Fi 網路名稱輔助判斷。

本文分享作者打造 Muffle 的經驗:透過地理圍欄,在會議、圖書館或宗教場合自動切換手機音量。由於 Android 持續高精度定位非常耗電,作者改採 Google Play Services 的 GeofencingClient,以較低功耗換取可接受的觸發延遲,並設定 60 秒 loitering delay 確認使用者真的停留在現場。為避免 GPS 漂移造成誤判,系統在退出後還會加入緩衝時間,且會在開機後重新註冊 geofence。作者強調,情境自動化不能只依賴單一感測器,必須用多層驗證來兼顧便利與穩定。

06

How we adapted our bottom navigation into a navigation rail in KMP

Dev.to Kotlin 作者:Arfin Hosain 發布:08-30 03:47

我們如何在 KMP 中將底部導覽改造成 Navigation Rail

從僅支援手機到同時支援手機與平板,只多了一個容器檔案和一個小型共享函式。

重點摘要

用一次共享的寬度判斷,決定顯示底部導覽列或側邊 rail。
Rail 幾乎完全重用既有的目的地、動畫、顏色與觸覺回饋。
KMP 與 Compose Multiplatform 讓手機和平板版面共用同一套程式碼。

Foster 是一款以 Kotlin Multiplatform 與 Compose Multiplatform 開發的關係打卡應用。當它在平板上測試時,原本的手機式底部導覽列顯得過度拉伸,因此團隊以極少的新程式碼加入側邊 navigation rail。應用外殼只需一次寬度判斷,即可在底部導覽列與 rail 間切換;共享模組中的 width size class 函式則統一決定何時視為平板尺寸。大部分 rail 邏輯直接沿用既有導覽列,包括目的地、樣式、動畫與觸覺回饋。文章強調,在共享 UI 與邏輯下,支援新裝置尺寸多半只是重用既有決策,而非重做一個版本。

07

Kotlin Weekly #526

Kotlin Weekly 作者: 發布:08-30 05:58

Kotlin Weekly #526

JetBrains 釋出 1.12.0,包含為 Compose Hot Reload 的 AI 程式代理提供的實驗性 MCP 伺服器、Web 目標的自動字型回退,以及可更細緻控制桌面視窗與對話框狀態的 v2 API。

重點摘要

Compose Multiplatform 1.12.0 新增 Hot Reload 的 AI 代理實驗性 MCP 支援
文章涵蓋以 Flyway migration 產生 jOOQ 程式碼,以及可編譯安全的行動端 mock server
本期也收錄 Android 效能優化案例、Kotlin 講座與多個新 KMP 函式庫

Kotlin Weekly #526(2026 年 8 月 30 日)重點介紹 Compose Multiplatform 1.12.0:新增供 AI 程式代理使用的實驗性 MCP server、Web 目標的自動字型回退,以及可更精細控制桌面視窗與對話框狀態的 v2 API。內容同時收錄實務文章,包含如何直接從 Flyway SQL migration 產生 jOOQ 程式碼而不必依賴正式資料庫,以及為行動應用打造可編譯安全的 mock 伺服器。另有 Android 最佳化案例、AI 時代的 Kotlin 教學影片與多款涵蓋序列化、UI 保護、架構分析、密鑰掃描和 KMP 圖形的函式庫介紹。

08

Kotlin Doesn’t Distrust Your Variable. It Refuses to Trust Assumptions It Cannot Prove.

Medium Kotlin 作者:Ahmed Elkrrai 發布:08-30 00:07

Kotlin 並不是不信任你的變數,而是拒絕相信無法證明的假設。

Smart cast 是 Kotlin 最優雅的特性之一。

重點摘要

Kotlin 的 smart cast 被視為非常優雅的語言特性。
文章主旨在於:Kotlin 只接受能被證明的假設。
這種設計反映出 Kotlin 對型別安全的重視。

本文聚焦於 Kotlin 的 smart cast,以及其背後的語言設計哲學。Kotlin 並非「不信任」變數,而是只接受自己能夠驗證的假設,藉此維持程式碼的安全與清晰。標題強調,這不是懷疑,而是建立在可證明保證上的行為。從目前可見的內容來看,文章核心是在說明 Kotlin 如何以明確、可檢查的方式取代不安全的便利性。