Daily Digest

每日新聞摘要

2026年11月01日

今日總結

📝 今日焦點:Folio、無網路權限檢視器、Purple TV、Plavio 與外勤同步 App,延續以隱私、離線與裝置端運作為核心的產品取向。 🔧 效能最佳化:FinLedger 透過移除主執行緒重工作、合併 Flow、加入 debounce 與穩定性設定,讓 Compose 清單更順。 🏗 架構設計:Muffle 與 AppFunctions/AppState、Android AI agent 內容顯示本機優先、以註解驅動工具與分層同步的設計取捨。 ✅ 測試與品質:FinLedger 來自真實使用者回饋修正登入、備份、匯出與信用卡計算問題,顯示公開上線後仍需持續打磨。

01

I built an Android file viewer that has no internet permission

Dev.to Kotlin 作者:Vishal Solanki 發布:11-01 08:08

我做了一款沒有網際網路權限的 Android 檔案檢視器

這個 App 完全不要求 INTERNET 權限;不是「我們不蒐集資料」,而是 Android 根本不讓它開啟 socket。

重點摘要

Folio 可開啟 PDF、Office 文件、文字、程式碼、圖片、音訊/影片與 ZIP。
它同時不申請網際網路與儲存空間權限,改用 Storage Access Framework。
核心實作採 Kotlin、Jetpack Compose,以及多個本機處理的解析器與函式庫。
展開詳細摘要

作者在厭倦了充滿廣告、登入與過度權限的檔案檢視器後,自行打造了免費的 Android App Folio。它最重要的設計原則是完全不申請 INTERNET 權限,也不要求儲存空間權限,而是透過 Android 的 Storage Access Framework,只存取使用者明確開啟或授權的檔案與資料夾。Folio 支援 PDF、Office、文字、圖片、音訊/影片與 ZIP 等多種格式,並刻意讓 Word、Excel、PowerPoint 只能檢視。文章也介紹了離線回饋、當機回報、更新檢查與 GitHub Releases 發佈方式等做法。

02

Week 1 of Shipping a Privacy-First Finance App: What I Didn't Expect

Dev.to Kotlin 作者:DEVANSHU PATIL 發布:11-01 13:00

隱私優先財務 App 上線第 1 週:我沒料到的事

在將設計原則開源並於 Google Play 上架 FinLedger 一週後,最重要的體悟都來自真實使用者。

重點摘要

使用者對不必強制登入雲端的 App 反應正面。
offline-first 不等於只能綁在單一裝置上,資料可攜性很重要。
信用卡重複計算問題引發廣泛共鳴。
展開詳細摘要

FinLedger 在 Google Play 上架一週後,作者從真實使用者身上驗證並修正了許多假設。最直接的回饋是:大家很珍惜不必強制登入、立刻就能使用的財務 App,這顯示隱私與即時開啟本身就是明顯優勢。同時,使用者也提醒他,offline-first 不能代表資料被困在單一裝置,因此 FinLedger 提供加密的本機備份、私人的 Google Drive 同步,以及可匯出的 CSV 與 PDF。另一個廣受討論的議題是信用卡重複計算:刷卡與後續繳款不應都算成支出。文章最後指出,公開上線只是持續打磨的開始,接下來會聚焦更安全的編輯、更多期別報表與裝置端 SMS 智慧分析。

03

One feature in Flutter, Swift, and Kotlin: three small regrets

Dev.to Kotlin 作者:Reese Cooper 發布:11-01 15:10

Flutter、Swift 與 Kotlin 的一個功能:三個小小的遺憾

我在三個框架中都做了同一個功能——帶離線快取與下拉重新整理的清單——而遺憾幾乎完全相同。

重點摘要

Flutter 的 UI 很簡單,但必須把狀態留在 widget 樹外。
SwiftUI 介面優雅,卻在導覽狀態上變成 enum 和 path 的組合。
Kotlin 的 coroutine 讓非同步更順手,但生命週期處理容易出現難重現的洩漏。
展開詳細摘要

作者把同一個具離線快取與下拉重新整理的清單功能,分別實作於 Flutter、Swift 與 Kotlin。Flutter 的難點不是 UI,而是理解 widget 重建只有在你讓它變便宜時才真的便宜,因此必須把狀態移出樹狀結構。SwiftUI 看起來優雅,卻在導覽狀態上變得複雜,iOS 審查也可能揪出你沒測過的畫面。Kotlin 則受惠於 coroutine 的非同步體驗,但生命週期綁錯物件會造成難以重現的洩漏。真正的重點不是清單本身,而是快取失效與空白狀態。

04

From 28 to 60 fps: my own Twitch app for a 2017 TV

Medium Kotlin 作者:Vito Famiglietti 發布:11-01 11:44

從 28 到 60 fps:我為 2017 年電視打造的 Twitch 應用程式

Purple TV 是一款 Android TV 的非官方 Twitch 用戶端。

重點摘要

Android TV 的非官方 Twitch 用戶端
可在 2017 年的 Sony 電視上執行
可用 60 fps 播放 1080p60
展開詳細摘要

Purple TV 是一款為 Android TV 打造的非官方 Twitch 用戶端。作者表示,在他的 2017 年 Sony 電視上,這個應用程式可以以 60 fps 播放 1080p60 影片;相較之下,官方 Twitch App 在同一裝置上的表現較差。文章重點在於,透過客製化方案,舊款電視硬體也能獲得更流暢的播放體驗。

05

I built an Android file viewer that has no internet permission

Medium Kotlin 作者:Vishal Solanki 發布:11-01 12:30

我打造了一款不需要網路權限的 Android 檔案檢視器

我試過的許多 Android 檔案檢視器,不是要求存取整個儲存空間、就在頁面之間插入廣告,就是為了打開檔案而要求登入。

重點摘要

不需要網路權限。
許多檔案檢視器要求過度的儲存空間存取。
有些 App 會以廣告或登入流程干擾閱讀。
展開詳細摘要

本文介紹一款沒有網路權限的 Android 檔案檢視器,起因是作者對既有 App 的不滿:它們常要求存取整個儲存空間、在頁面間插入廣告,或為了開啟檔案而強迫登入。這段內容把專案定位為對這些常見問題的回應,強調隱私與簡潔,但未宣稱其他功能或效能表現。

06

snapshotFlow vs derivedStateOf: Which One, and When

Medium Kotlin 作者:Ramadan Sayed 發布:11-01 14:01

snapshotFlow 與 derivedStateOf:該用哪一個,以及何時使用

兩者都會觀察 Compose 狀態並對變更作出反應。

重點摘要

兩者都會觀察 Compose 狀態並回應變更。
它們不是彼此替代的選項。
關鍵差異不在於它們觀察什麼。
展開詳細摘要

snapshotFlow 與 derivedStateOf 都會觀察 Compose 狀態並對變更作出反應,但兩者並不是可互相替代的方案。文章強調,區分它們的重點不在於「觀察哪些狀態」,而是各自用途不同。在 Compose 中應依實際需要選用,而不是假設其中一個可以直接取代另一個。

07

Kotlin Weekly #535

Kotlin Weekly 作者: 發布:11-01 08:11

Kotlin Weekly #535

本期重點包括 Shipaton 2026 得主、Kotlin 2.5.0-Beta2,以及 KotlinConf 2027。

重點摘要

新聞涵蓋 Kotlin 更新、Android 工具與 Gemini 4 Carbon。
Multiplatform 單元收錄 Compose 與 Kotlin 共用程式碼相關文章。
函式庫區整理了尚在早期階段的工具、排程器與 AI 專案。
展開詳細摘要

Kotlin Weekly #535 發行於 2026 年 11 月 1 日,整理了近期 Kotlin 生態系動態,包括 Shipaton 2026 得主、Kotlin 2.5.0-Beta2、《State of Kotlin in 2026》報告,以及將在克拉科夫舉行的 KotlinConf 2027。內容也收錄 Android Dev Summit 的工具與效能更新,例如供 agents 使用的 Android CLI 新指令、Compose 重組追蹤與 AGP 9.3 中的 R8,並提到 Android Studio Rabbit 2 已穩定及 Bring Your Own Agent。另有 Multiplatform 文章、贊助資源與多個仍屬早期階段的函式庫專案。

08

Architecting for Privacy: Why I Chose Local-Only Data Storage Over Firebase for Muffle

Dev.to Kotlin 作者:Haseeb 發布:11-01 00:10

以隱私為核心的架構選擇:我為 Muffle 放棄 Firebase、改用純本地儲存

對於處理個人敏感資料的工具來說,採用純本地架構同時是一種隱私選擇與技術取捨。

重點摘要

Muffle 採用 offline-first 設計,讓敏感的行程與位置資料留在裝置上。
以 Room 本機儲存與 GeofencingClient 實作核心邏輯,避免雲端同步與伺服器驗證。
純本地架構讓重開機復原、背景服務與各家 OEM 的限制變得更複雜。
展開詳細摘要

作者說明為何 Muffle 採用 offline-first 的 Android 架構,而不是依賴 Firebase 或其他雲端後端。這個應用要依據祈禱時間、會議與地理圍欄位置自動調整鈴聲模式,因此他選擇把敏感資料留在裝置內。Room 以本機方式保存例行設定與 geofence 規則,GeofencingClient 觸發後直接驅動 AudioManager,無需把座標送往伺服器。這種做法提升隱私,也能在沒有網路時運作,但代價是系統重啟後的排程恢復、背景服務持久性、WakeLock 與不同 OEM 的省電限制都必須額外處理。文章最後指出,對隱私敏感的工具型 App 而言,純本地設計能降低安全與合規負擔,但開發者必須承擔更多可靠性責任。

09

Android AppFunctions Is in Beta. The Code Is Still Alpha

Dev.to Kotlin 作者:Dishant Sharma 發布:11-01 02:32

Android AppFunctions 已進入 Beta,但程式碼仍停留在 Alpha

發表走在程式碼前面:AppFunctions 對外稱為 beta,但 Jetpack 工件仍是實驗性預覽。

重點摘要

AppFunctions 會把帶註解的 Kotlin 函式變成可由 agent 在 App 內呼叫的本機工具。
必須具備 android.permission.EXECUTE_APP_FUNCTIONS,且裝置需為 Android 16 以上。
KDoc 註解會成為工具描述,寫好中繼資料和寫好程式碼同樣重要。
展開詳細摘要

Android AppFunctions 被宣告為「正式進入 beta」,但其背後的 Jetpack 函式庫仍是 1.0.0-alpha10,文件頁面也仍標示為 experimental preview。這項功能讓 App 充當本機 MCP server:OS 會索引帶註解的 Kotlin 函式,agent 可在 App 內、透過本機程序直接呼叫,不需經過網路。不過它受限於 Android 16、compileSdk 36 與 EXECUTE_APP_FUNCTIONS 權限,實際可觸及的裝置與使用者仍很有限。文章強調,KDoc 不再只是文件,而是 agent 讀取的工具描述;對多數團隊而言,現在更像是學習與試驗,而非真正的產品決策。

10

Building an Android AI Agent, Part 11: Mid-Task Replanning Without Starting Over

Dev.to Kotlin 作者:StareBrain 發布:11-01 04:15

打造 Android AI Agent,第 11 部分:在任務中途重新規劃而不必重頭開始

任務沒有失敗——失敗的是第三步的計畫。

重點摘要

重新規劃應保留已完成步驟,只重建剩餘部分。
將已完成步驟、失敗步驟、失敗原因與目前畫面快照提供給 LLM。
同一步驟反覆失敗,或已確認的動作仍失敗時,不適合重新規劃。
展開詳細摘要

第 11 部分說明 Android AI agent 如何在步驟失敗後,不必整個任務重來,而是針對剩餘步驟重新規劃。做法是把已完成步驟、失敗步驟、失敗原因與目前畫面快照送給 LLM,要求它只產生後續的新步驟。文章也示範如何把畫面狀態壓縮成精簡提示、如何將修訂後的步驟合併回任務,以及哪些情況不該重新規劃,例如同一步驟連續失敗,或使用者已確認的動作仍然失敗。

11

My Jetpack Compose List Was Dropping Frames on ₹ Signs — Here's the Fix

Dev.to Kotlin 作者:DEVANSHU PATIL 發布:11-01 04:30

我的 Jetpack Compose 清單在 ₹ 符號上掉幀了——這是修正方法

FinLedger 追查出 UI 卡頓來自主執行緒工作、Flow 震盪與不穩定模型,並重構管線以維持順暢的 60/120fps 捲動。

重點摘要

將清單分組、排序與格式化移出主執行緒
把多個 Room Flow 整併為共享的熱 StateFlow 串流
改用 collectAsStateWithLifecycle 並加入 Compose 穩定性規則
展開詳細摘要

FinLedger 發現,Jetpack Compose 的交易清單之所以掉幀,是因為大量列表運算都跑在主執行緒上,多個 Room Flow 也各自觸發 emission,而不穩定的模型類別則導致不必要的重組。團隊透過重構資料管線,將分組、排序與格式化移到 Dispatchers.Default,加入搜尋 debounce,將 8 個 Flow 整併為 3 個共享熱串流,改用 collectAsStateWithLifecycle,並在 compose_stability.conf 中標記核心模型的穩定性。結果是捲動更流暢,啟動更快,記憶體尖峰也下降了。

12

I built Plavio — a free streaming app for Android and Android TV

Dev.to Kotlin 作者:Najam 發布:11-01 06:16

我打造了 Plavio——一款適用於 Android 與 Android TV 的免費串流應用程式

Plavio 是一個由多個元件協同運作的小型系統。

重點摘要

Plavio 由應用程式、PlavioHD、PMeta 與 Plavio Search 組成。
針對慢速網路設計,PlavioHD 會在伺服器端檢查並快取串流。
這款應用程式免費、無廣告,且手機與電視共用同一帳號與資料庫。
展開詳細摘要

作者介紹自己打造的 Plavio,這是一款面向 Android 手機與 Android TV 的串流應用程式,由多個元件協同運作。主程式提供介面與播放器,PlavioHD 負責電影、影集與直播串流,PMeta 提供海報、演員、評分與完整資訊,Plavio Search 則讓標題能更快被找到。作者也提到可加入其他外掛,例如播放器、字幕、下載與 debrid 支援。產品特別考量慢速網路,PlavioHD 會在伺服器端檢查並快取串流,讓應用程式內幾乎能立即開啟播放;同時它免費、無廣告,手機與電視版本可共用同一帳號與資料庫。

13

Android Dev Summit 2026: Google brings developers back together after four years and puts agents at…

Medium Kotlin 作者:Diego Ferreira Caetano 發布:10-31 20:44

Android Dev Summit 2026:Google 在四年後再次召集開發者,並將代理置於焦點

這是一篇關於自 2022 年以來首屆 Android Dev Summit 的簡報:Google 發表了什麼、各項內容成熟度如何,以及如何透過程式碼使用它們。

重點摘要

自 2022 年以來首屆 Android Dev Summit
整理 Google 的宣布內容與各項功能成熟度
附上程式碼範例說明實際用法
展開詳細摘要

本文整理自 2022 年以來首屆 Android Dev Summit 的重點,聚焦 Google 發表了哪些內容、各項功能目前成熟到什麼程度,以及實際上該如何使用,並搭配程式碼示範。文章面向 Android 開發者,提供一份簡明的會議摘要,特別強調各項能力的成熟度與使用方式,而非將所有內容視為已完全穩定。

14

How I’m Building a Field Ops App for Places Without Reliable Internet

Medium Kotlin 作者:Taufik Fredi Pratama 發布:11-01 00:00

我如何為網路不穩定的地點打造一款外勤作業應用程式

我正在先打造傳送引擎,而不是先做畫面。

重點摘要

這款應用程式是為網路不可靠的環境而設計。
開發順序是先做傳送引擎,再做介面。
工作先儲存在裝置上,之後再取得伺服器確認。
展開詳細摘要

這篇文章說明作者正在打造一款適用於網路不穩定地點的外勤作業應用程式。作者表示自己會先建立傳送引擎,而不是先做畫面,重點放在底層工作流程而非介面。核心概念是先把工作內容儲存在裝置上,再等待伺服器確認,反映出適合間歇性連線情境的同步設計。文章強調這是架構上的關鍵取捨,而不是先以 UI 為中心的開發方式。

15

Is ViewModel Dead? AppState Is Coming

Medium Kotlin 作者:Chetan Gupta 發布:11-01 03:10

ViewModel 已經過時了嗎?AppState 正要登場

Google 以 AppState 之名推出了兩個 alpha 函式庫,而指南展示了 Compose State 可在 repository、service 等層級運作……

重點摘要

Google 以 AppState 之名釋出了兩個 alpha 函式庫。
指南展示了 Compose State 可用於 repository、service 等層級。
文章以此引出 AppState 是否會取代 ViewModel 的疑問。
展開詳細摘要

Google 以 AppState 之名推出了兩個 alpha 函式庫,並在相關指南中展示 Compose State 可運作於 repository、service 等多個層級。文章藉此提出一個問題:隨著 AppState 的出現,ViewModel 是否正在走向過時。不過這些函式庫仍處於 alpha 階段,因此內容應理解為一項早期提案或探索,而不是已完成的正式替代方案。文章重點在於呈現 Google 正在嘗試的方向,而非宣稱 AppState 已全面取代既有架構模式。

16

Build the socket before you buy the

Medium Kotlin 作者:Ali Ziwa 發布:11-01 03:38

先把 Socket 建好,再去找 Tenant

A model is a tenant. Build the room before you advertise it.

重點摘要

以 room 與 tenant 的比喻來說明概念。
先完成底層結構,再對外宣傳。
原文很短,並引導讀者到 Medium 繼續閱讀。
展開詳細摘要

這段文字用簡短的比喻說明:model 就像 tenant,應該先把 room 建好,再去宣傳。重點在於先準備好底層結構,再對外展示或推廣,而不是在基礎尚未完成時就急著曝光。原文內容非常精簡,並以「Continue reading on Medium」作結,因此未提供更多技術細節。

17

TextFieldState vs TextFieldValue in Jetpack Compose: I Built the Same Login Form Twice

Medium Kotlin 作者:Aslam Hossin 發布:11-01 07:01

Jetpack Compose 中的 TextFieldState 與 TextFieldValue:我把同一個登入表單做了兩次

為什麼 `BasicTextField(state)` 能消除非同步游標跳動 bug、簡化 ViewModel 驗證,並刪掉 35 行樣板碼。

重點摘要

比較 Jetpack Compose 中的 `TextFieldState` 與 `TextFieldValue`。
主張 `BasicTextField(state)` 可避免非同步游標跳動 bug。
說明它如何簡化 ViewModel 驗證與樣板碼。
展開詳細摘要

本文透過兩次重做同一個登入表單,對比 Jetpack Compose 裡的 `TextFieldState` 與 `TextFieldValue`。作者認為,使用 `BasicTextField(state)` 可以消除非同步造成的游標跳動問題,讓以 ViewModel 為中心的驗證邏輯更簡潔,也能減少不少樣板碼。文章重點放在 Compose 表單處理的實務取捨,特別是狀態管理與文字輸入行為。