Daily Digest

每日新聞摘要

2026年03月30日

今日總結

內容會跟隨語言切換。

📝 今日焦點: 注意 Task/back stack 與 launchMode 的陷阱、Android 17 相容性風險,以及遠端下發 Compose 的部署、回滾與監控考量。 🔧 效能最佳化: 啟用 AGP 8.12 的 optimizedResourceShrinking 可大幅移除未用資源,並評估 KAP 在多服務編排下的效能與可預測性。 🏗 架構設計: 將導覽納入 Compose 架構,採單 Activity + Navigation 或合適的模式混合,並以 Version Catalogs 集中管理相依以維持可維護性。 ✅ 測試與品質: 以單元測試驗證 Koin 註解與編譯器行為,測試 remember 與 TextField 邊界,並用 StateFlow/SharedFlow/Channel 處理旋轉事件以避免遺失。

01

Day 5/100: Intent, Task & Back Stack and Why launchMode is a trap

Dev.to Kotlin 作者:Hoang Son 發布:03-30 08:04

Day 5/100:Intent、Task 與 Back Stack,為何 launchMode 是陷阱

Task 為系統管理的 Activity 堆疊,錯誤使用 launchMode(特別是 singleTask)會重用 Activity 並清除其上方整個堆疊,導致意外的返回行為。

重點摘要

Task 是系統層級的 Activity 堆疊
singleTask 會清除目標上方整個堆疊
使用 Intent flags 與 TaskStackBuilder 或 Navigation Component 修正返回行為

本文說明 Android 的 Task 與 back stack 機制,並解析為何濫用 launchMode 會造成難以重現的錯誤。Task 屬於作業系統而非單一 App,可能在不同 Task 中存在相同的 Activity,導致 Back 行為差異。launchMode 有 standard、singleTop、singleTask、singleInstance;singleTop 常用於通知以避免重複實例,singleTask 則會在重用 Activity 時清除其上方的整個堆疊,容易引發問題。建議以 Intent flags(如 CLEAR_TOP、NEW_TASK|CLEAR_TASK、REORDER_TO_FRONT)做更精準的啟動控制;對深度連結可用 TaskStackBuilder 或 Navigation Component 來合成合理的返回堆疊,並注意 taskAffinity 的隱性影響。總結:以預設為主、必要時用 flags 或 TaskStackBuilder,或採單 Activity + Navigation Component 以簡化管理。

02

R8 optimizedResourceShrinking: Reduce Android APK Size by 50%

Dev.to Kotlin 作者:SuriDevs 發布:03-30 10:15

R8 optimizedResourceShrinking:將 Android APK 大小減少約 50%

Google 將資源縮減整合到 R8 的優化流程,使 R8 同時分析程式可達性與資源引用,能更徹底移除未使用資源。

重點摘要

在同一個 R8 管線同時做程式與資源分析,能移除僅被死碼引用的資源
透過 android.r8.optimizedResourceShrinking=true 並在 release 開啟 minify 與 shrinkResources 來啟用
動態按字串載入或反射取資源會導致資源被移除,需改用直接引用或加 keep 規則

過去資源縮減因 AAPT2 產生無條件的 keep 規則且在代碼優化後執行,常遺漏未使用資源。AGP 8.12 的 optimizedResourceShrinking 將資源縮減併入 R8 的優化流程,讓 R8 同時判斷程式可達性與資源引用關係,把僅被死碼引用的資源與該死碼一併移除。啟用方法是在 gradle.properties 設定 android.r8.optimizedResourceShrinking=true,並在 release 建置啟用 minify 與 shrinkResources。Google 表示含大量未用函式庫資源的專案可節省 50% 以上,但實際效果視專案結構而定。需注意動態載入、反射、WebView 的資源路徑與多模組命名衝突,必要時加入 keep 規則並完整測試。

03

Mastering Koin Annotations with the Koin Compiler Through Unit Tests

Medium Kotlin 作者:Tezov 發布:03-30 07:31

透過單元測試與 Koin 編譯器精通 Koin 註解

本文示範如何將 Koin 註解與 Koin 編譯器結合,並以單元測試驗證,文章末提供原始碼。

重點摘要

聚焦 Koin 註解與 Koin 編譯器
以單元測試實際運行並驗證註解生成的行為
文章結尾提供可下載的原始碼並連結至 Koin Developers

作者 Tezov 以實務導向的方式說明如何結合 Koin 註解與 Koin 編譯器,並透過單元測試來驗證註解與編譯器處理後的行為。文章強調以測試作為驗證手段,讓開發者能夠實際運行、檢視並確認註解驅動的元件與編譯結果。全文在 Koin Developers 平台上發表,並在文章末提供原始碼供讀者下載與實作參考,方便 Kotlin 開發者檢驗、重現與調整其註解與相依設定。

04

Day 8 — Navigation in Jetpack Compose: Building Real Multi-Screen Apps

Medium Kotlin 作者:Yodgorbek Komilov 發布:03-30 07:35

第8天 — Jetpack Compose 的導覽:建構真正的多畫面應用

在前七天專注於單一畫面的 UI、狀態與架構後,本篇轉向 Jetpack Compose 的導覽,探討如何建構多畫面應用。

重點摘要

焦點從單一畫面轉為導覽
說明在 Compose 中組織多畫面應用
探討導覽對狀態與架構的影響

第8天將焦點從前七天在單一畫面上關注的 UI、狀態與架構,轉向 Jetpack Compose 的導覽,以建構真正的多畫面應用。文章說明為何需要突破單一畫面的限制,並將導覽視為組織路由、管理畫面流程與在 composable 間呈現導覽相關狀態的機制,提出將導覽納入應用架構的模式與實務考量,使應用能從單一視圖擴展為連貫的多畫面體驗。本篇作為前七天內容的延續,旨在提供讀者概念性與可操作的做法,協助處理後退堆疊、保留跨畫面狀態與規劃路由,將原型轉為可在生產環境使用的多畫面 Compose 應用。

05

A Hidden Problem in Jetpack Compose TextField Max Length

Medium Kotlin 作者:inDrive.Tech 發布:03-30 09:12

Jetpack Compose TextField 最大長度的隱藏問題

從在 inDrive 建立設計系統的經驗中學到的教訓。

重點摘要

揭示 Jetpack Compose TextField 最大長度的隱藏問題
分享建立 inDrive 設計系統的實務經驗與教訓
提供前往 inDrive.Tech 閱讀完整文章的連結

本文簡短指出 Jetpack Compose 中 TextField 最大長度行為的一個隱藏問題,並以在 inDrive 建立設計系統的經驗作為背景說明。文章提醒開發者與設計師,字元限制與輸入處理在現代 UI 工具庫中可能產生意外行為,這些問題會影響元件設計、驗證流程與開發工作流程。文章並非在此詳述所有技術細節,而是以實務經驗為出發,建議讀者參考 inDrive.Tech 的完整文章以取得具體範例與實作建議,強調在實作文字輸入限制時應測試邊界情況。

06

Using Gradle Version Catalogs to modernise Gradle Projects

Medium Kotlin 作者:Parser 發布:03-30 09:41

使用 Gradle Version Catalogs 現代化 Gradle 專案

介紹如何透過 Gradle 版本目錄(Version Catalogs)來簡化與現代化 Gradle 的建置設定。

重點摘要

說明 Gradle Version Catalogs 的用途與優勢
強調集中管理相依與插件以提升一致性
作者 Dionisio Cortés Fernández,刊於 Medium(Parser)

本文由 Dionisio Cortés Fernández 在 Parser 的 Medium 發表,介紹 Gradle Version Catalogs 並說明其在現代化 Gradle 專案中的角色。文章提出使用版本目錄可以將相依與插件的宣告集中管理,提升多模組專案的一致性,並讓升級與維護過程更可預期且更安全。作者將版本目錄視為邁向更清晰、可維護建置設定的實用步驟,並提到遷移時需考量的要點,例如目錄結構、別名管理與多模組協調。完整範例與實作細節請參閱原文,但此篇提供了評估與採用 Version Catalogs 的入門導引。

07

Jetpack Compose State Basics: How remember Really Works

Medium Kotlin 作者:Syntax Buddy 發布:03-30 12:03

Jetpack Compose 狀態基礎:remember 的真實運作方式

如果你曾使用 Jetpack Compose,應該見過一行使用 remember 的程式碼;本文釐清 remember 的實際運作原理。

重點摘要

說明 remember 在 Compose 中的用途
解釋 remember 如何在重新組合(recomposition)中保留值
整理常見用法與需要注意的盲點

本文聚焦 Jetpack Compose 的狀態基礎,特別說明 remember 的運作。文章從開發者常見的一行程式碼切入,說明 remember 用來在組件重新組合時保留局部值的目的與保障。內容闡述 remember 在 Compose 狀態管理中的定位,說明它在重新組合過程中能維持值穩定的行為,並提示常見誤解與實務上的注意事項。整體上,文章提供對 remember 概念與使用時機的清晰說明,幫助開發者正確管理元件內的狀態。

08

Don’t Update to Android 17 Until You Read This

Medium Kotlin 作者:AndroidLab by Andre 發布:03-30 13:03

在更新到 Android 17 前請先閱讀這篇文章

Android 17「Cinnamon Bun」帶來 App Bubbles、AI agents、智慧化隱私與可能影響開發者的破壞性變更。

重點摘要

加入 App Bubbles 改善多工體驗
引入 AI agents 提供新型自動化功能
包含可能影響應用相容性的破壞性變更

Android 17(代號「Cinnamon Bun」)推出 App Bubbles、AI agents 與更聰明的隱私控管,同時也帶來會影響開發者的破壞性變更。文章提醒使用者與開發者在升級前務必了解細節:一般使用者應評估新功能是否符合需求並先備份裝置;開發者則需檢查相容性、更新相關函式庫並完整測試應用,避免升級後發生執行錯誤或功能異常。總之,Android 17 在多工、智慧化與隱私方面有進步,但因相容性風險,建議謹慎準備與測試後再升級。

09

How to Implement Remote Compose in Android

Medium Kotlin 作者:AndroidLab by Andre 發布:03-30 13:14

在 Android 中實作 Remote Compose

如何從伺服器動態渲染 Jetpack Compose UI,並改變你的應用程式開發流程

重點摘要

以後端下發的介面描述在裝置端即時渲染 Compose 畫面
可加速 UI 更新、進行 A/B 測試及實現個人化,無需重新上架
實作需考量效能、離線支援、安全驗證與相容性

本文介紹如何將 Jetpack Compose 的 UI 從伺服器端動態下發並在 Android 裝置上即時渲染,說明系統架構、資料流與關鍵元件。作者描述以介面描述檔或模板由後端傳送,裝置端透過解析器與渲染層將描述轉換為 Compose 畫面,並討論此做法帶來的好處──加快 UI 更新與 A/B 測試、支援個人化與功能開關,無需重新上架即可變更介面;同時提醒實作時需關注效能、離線支援、安全驗證、測試與向下相容等議題。結論強調遠端 Compose 會改變開發流程,值得在掌握版本與備援策略後評估導入。

10

Android Design Patterns & Architecture Patterns

Medium Kotlin 作者:Riyas Pullur 發布:03-30 13:39

Android 設計模式與架構模式

現代 Android 應用會結合創建型、結構型、行為型與架構型模式,以建立可擴展且易於維護的系統。

重點摘要

結合創建型、結構型、行為型與架構型模式
透過模式組織程式碼以提升可擴展性與可維護性
多種模式並用可改善重用性、可測試性與程式碼清晰度

現代 Android 開發通常同時運用多種設計與架構模式,包括創建型、結構型、行為型與架構型,來打造可擴展且易於維護的應用。創建型模式處理物件建立,結構型模式處理組合與關係,行為型模式處理物件間的互動與責任分配,而架構型模式則決定整體應用的組織與資料流。這些模式有助於分離關注點、提升可測試性、降低重複並讓程式碼意圖更明確。實務上會在物件層、元件層與系統層混合使用不同模式,依需求在可讀性、重用與效能間取得平衡,正確選用各類模式是設計穩健 Android 應用的關鍵。

11

Stop wiring async calls manually (Kotlin coroutines)

Dev.to Kotlin 作者:Damián Rafael Lattenero 發布:03-30 01:06

別再手動串接非同步呼叫(Kotlin 協程)

KAP 讓平行工作、相依性與階段在程式碼中顯式呈現,編譯通過就代表串接正確。

重點摘要

把平行工作與階段結構化顯示
不再手動傳遞或接線值
編譯時即可保證串接正確性

本文介紹 KAP,一個讓 Kotlin coroutine 編排更具結構性的輕量庫。原生 coroutine 容易把相依性與階段隱藏,且手動 await() 串接易造成類型相符卻邏輯錯置的錯誤。KAP 提供 DSL:.with 平行執行、.then 等待前一階段、.andThen 以先前結果為上下文,使依賴圖在程式碼中成為明確結構。範例顯示 13 個呼叫分成 6 個階段且無需手動傳遞值。效能與原生 coroutine 相當,無反射或執行時生成,具編譯時安全性(能編譯代表串接正確)。適用於多服務協調、儀表板、結帳流程與彙整管線;若只有一兩個 coroutine 呼叫則不需使用。

12

Advanced Kotlin Part 6: Abstract Classes in Kotlin — Defining Common Rules

Medium Kotlin 作者:Kishor Ramani 發布:03-30 02:31

進階 Kotlin 第六篇:Kotlin 的抽象類別 — 定義共通規則

抽象類別允許你為相關類別定義共同結構,同時強制具體子類提供特定實作。

重點摘要

為相關類別定義共通結構。
強制子類提供具體實作。
文章引導讀者深入探索 Kotlin 中的抽象類別。

此篇 Advanced Kotlin 系列短文介紹抽象類別在 Kotlin 的用途:於相關類別間定義共同結構,並強制具體子類提供特定實作。說明抽象類別兼具提供共享成員以減少重複與透過抽象方法或屬性要求子類完成必要實作的雙重角色。文章視抽象類別為設計一致 API 與引導實作的工具,並引導讀者到 Medium 連結查看範例與更深入說明,強調在重用與客製化間取得平衡的重要性。

13

Advanced Kotlin Part 7: Interfaces in Kotlin — Multiple Inheritance Made Easy

Medium Kotlin 作者:Kishor Ramani 發布:03-30 04:31

Advanced Kotlin Part 7:Kotlin 中的介面 — 讓多重繼承更簡單

介面允許類別實作多個契約,使單一類別能同時符合多種行為規範。

重點摘要

介面可讓類別實作多個契約。
與抽象類別不同,介面可以被多重實作。
介面讓類似多重繼承的模式在 Kotlin 中更容易處理。

本文說明 Kotlin 中的介面如何讓類別實作多個契約,使單一類別能同時符合多種行為規範。與抽象類別不同,抽象類別在繼承上較受限制,而介面可以被多重實作,提供一種輕量且可組合的方式,達成多重繼承的目的但避開其複雜性。此特性有助於模組化設計、職責分離與可重用性,使類別能扮演多重角色,提升程式測試性與 API 清晰度。總之,介面使得在 Kotlin 中管理多重繼承模式變得更為容易。

14

Understanding Type Inference in Kotlin (with Decompiled Java Code)

Medium Kotlin 作者:Sandeep Kulkarni 發布:03-30 06:39

理解 Kotlin 的型別推斷(含反編譯後的 Java 程式碼)

Kotlin 以型別推斷作為使語法簡潔且具表現力的關鍵,本文以反編譯的 Java 範例說明其運作。

重點摘要

Kotlin 語法簡潔且具表現力
型別推斷是減少冗贅的核心特性
以反編譯的 Java 程式碼來示範推斷結果

本文介紹 Kotlin 的型別推斷,說明它如何使語法更簡潔有表現力。作者透過將 Kotlin 編譯後的反編譯 Java 程式碼做比較,示範推斷出的型別如何在生成的程式中呈現,讓讀者看清編譯器的決策與實際產物之間的對應。此方法有助於理解何時可省略顯式型別、對 Java 互操作性的影響,以及推斷如何影響程式可讀性與開發者對底層行為的預期。文章適合想深入了解 Kotlin 型別推斷與編譯後表現的開發者閱讀。

15

StateFlow vs SharedFlow vs Channel in Android: Fix Duplicate UI Events the Right Way

Medium Kotlin 作者:Prasad Pawar 發布:03-30 06:44

StateFlow、SharedFlow 與 Channel 在 Android 的比較:正確修復重複 UI 事件

別再在旋轉時遺失 UI 事件或狀態。

重點摘要

避免在配置變更(如旋轉)時掉失事件與狀態。
提供企業級的 Kotlin UI State 與 Events 處理範式。
比較 StateFlow、SharedFlow 與 Channel 的適用情境。

本文說明 Android 常見問題:在裝置旋轉或其他配置變更時,UI 事件被遺失或狀態丟失。作者提出一套企業級的 Kotlin 處理範式,用以可靠管理 UI 狀態與事件,並比對 StateFlow、SharedFlow 與 Channel 三種主要機制,說明各自特性與適用時機。重點在於透過合適的反應式原語與生命週期感知的發送與收集策略,確保持久狀態能在旋轉後保留,同時一次性事件能正確且不重複地被傳遞,提供給架構師與開發者可維護的實務指引,避免因配置變更而產生的錯誤。