📝 Today’s focus: This issue spans Spring, Kotlin, Compose, Flow, and Android updates, with a common theme: specs should stay close to code, and architecture must remain testable and maintainable.
🔧 Performance: Cloudflare saved 100 TB of memory via DNS cache tuning; Compose allocation profiling cut hidden work, and an APK case showed size can drop from 100+ MB to 17.76 MB.
🏗 Architecture: DI-driven startup orchestration, multi-module templates, versioned encryption, and privacy-first local parsing make initialization, migration, and data handling more controllable.
✅ Testing and quality: Canceled uploads, Flow fusion, stack trace recovery, and certificate pin rotation all show that only testing, re-verification, and safe rollout prevent failures from masquerading as success.
🚀 Language evolution: Kotlin vs. Java selection is now use-case driven; Flow, channels, explicit backing fields, and KMP/tvOS work keep expanding JVM and cross-platform capabilities.
01
Java Weekly, Issue 663
Baeldung作者:baeldung發布:09-13 11:00
Java Weekly, Issue 663
From spec-driven development to living specifications in Java projects.
重點摘要
Spring and Java links focus on specs, tooling, and maintenance releases.
Technical essays explore agent memory, AI evaluation, and JVM debugging.
This week’s pick spotlights Cloudflare’s DNS cache optimization and large memory savings.
展開詳細摘要
This issue rounds up Java and JVM-related reading across Spring, Quarkus, Kotlin, Jetty, Vert.x, Elasticsearch, and Micronaut, along with webinars and upgrade announcements. The featured Spring piece argues for living specifications that stay close to code and remain testable as systems evolve. In the technical section, Werner Vogels compares useful agent memory to the brain, while other links examine AI evaluation, debugger use by agents, and context engineering. The week’s pick highlights how Cloudflare saved 100 terabytes of memory by optimizing its 1.1.1.1 DNS cache.
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 内存。
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 記憶體。
A "resolved" state that never resolves is just a renamed unknown
Dev.to Kotlin作者:StareBrain發布:09-13 09:24
A “resolved” state that never resolves is just a renamed unknown
If DENIED_UNRESOLVED is a terminal value that just sits in the log, I haven't removed the uncertainty — I've renamed it.
重點摘要
Unresolved states must be reconciled by an active process, not left as labels.
Token binding prevents parameter drift, but not world drift; both checks are needed.
The model also applies to on-device writes, not just external APIs.
展開詳細摘要
The author revisits a three-state execution model—EXECUTED, DENIED_CONFIRMED, and DENIED_UNRESOLVED—and explains that an unresolved state is only useful if it is eventually reconciled. Without recurring re-query, promotion on evidence, and escalation for stale cases, it becomes a renamed form of uncertainty. A commenter also reveals a second gap: parameter-bound confirmation tokens stop recipient or message drift, but not world drift such as a calendar slot filling or permissions changing. The piece concludes that both token binding and independent re-verification are required, and that the same honesty test applies to local writes as well as external providers.
Parsing bank statements in memory: keep the fields, store nothing else
Dev.to Kotlin作者:Royal Simpson Pinto發布:09-13 09:30
Parsing Bank Statements In Memory: Keep the Fields, Store Nothing Else
The privacy story is not a policy you have to trust; it is a shape the code physically has.
重點摘要
Files are parsed in memory and discarded before they touch disk or server storage.
CSV import is on-device, defensive, and rules-based, with caps and format checks.
Receipt OCR and categorization stay local, saving only the confirmed transaction fields.
展開詳細摘要
PennyRush is built around a narrow privacy contract: bank statements and receipts are read into memory, parsed, and then discarded before they are written to disk, storage, logs, or analytics. The app keeps only structured transaction fields such as amount, date, merchant, note, type, and category. CSV imports run fully on-device with defensive checks for file type, size, line count, headers, and malformed values. Receipt scanning uses on-device OCR through ML Kit, while merchant extraction and categorization rely on deterministic rules. The tradeoff is less automation and no silent reprocessing later, but the result is a system whose privacy guarantees come from its architecture, not just its policy.
在内存中解析银行对账单:只保留字段,不存其他内容
这套隐私承诺不是一份需要你信任的政策,而是代码本身的实际形态。
重點摘要
文件只在内存中解析,随后立即丢弃,不写入磁盘或服务器。
CSV 导入完全在设备端执行,并带有格式检查与大小限制。
收据 OCR 和商家分类都在本地完成,只保存确认过的交易字段。
展開詳細摘要
PennyRush 的核心隐私设计,是把银行对账单和收据先读入内存、解析后立刻丢弃,不写入磁盘、对象存储、日志或分析系统。系统只保留金额、日期、商家、备注、类型和分类等结构化字段。CSV 导入完全在设备端进行,并会检查文件类型、大小、行数、表头与异常值。收据扫描使用 ML Kit 的本地 OCR,商家提取与分类采用规则式处理。这样的做法虽然减少了自动化能力,也无法在之后静默重解析,但让隐私保证直接由架构本身支撑。
在記憶體中解析銀行對帳單:只保留欄位,不存其他內容
這套隱私承諾不是一份要你相信的政策,而是程式本身的實際形狀。
重點摘要
檔案只在記憶體中解析,之後立即丟棄,不寫入磁碟或伺服器。
CSV 匯入完全在裝置端執行,並具備格式檢查與大小限制。
收據 OCR 與商家分類都在本機完成,只保存確認過的交易欄位。
展開詳細摘要
PennyRush 的核心隱私設計,是把銀行對帳單與收據先讀入記憶體、解析後立刻丟棄,不寫入磁碟、物件儲存、日誌或分析系統。系統只保留金額、日期、商家、備註、類型與分類等結構化欄位。CSV 匯入完全在裝置端進行,並會檢查檔案類型、大小、行數、表頭與異常值。收據掃描則使用 ML Kit 的本機 OCR,商家擷取與分類採規則式處理。這種做法雖然少了部分自動化能力,但讓隱私保證直接由架構本身支撐。
One Flag, Two Checkpoints: How a Canceled Upload Reported Success
ProAndroidDev作者:Vitaliy Gribko發布:08-31 14:07
One Flag, Two Checkpoints: How a Canceled Upload Reported Success
A canceled upload was reported as a successful publication because two silent failures lined up at the wrong moment.
重點摘要
Interrupts are requests, not guarantees; swallowed exceptions can hide cancellation.
The executor never called onCancel(), so the cancellation flag stayed false.
The shipped fix set the flag first and added two checkpoints in the task.
展開詳細摘要
A bug in a short-video SDK let a canceled upload appear as a successful publication, leaving a ghost item in the grid until refresh removed it. The root cause was a pair of silent failures: the executor interrupted the worker but never set the cancellation flag, and the upload library swallowed the interrupt exception during polling and returned normally. Because routing depended on the flag, the task reported Done instead of Canceled. The eventual fix was deliberately small: set the flag before interrupting, then check it both during progress callbacks and after upload() returns. The article also explains why tests missed the issue and why a larger synchronous-cancellation API was later removed.
一个标志、两个检查点:被取消的上传为何报告成功
一次被取消的上传之所以被判定为成功,是因为两个无声的失误在错误时刻同时发生。
重點摘要
中断只是请求,不是保证;若异常被吞掉,取消就会失效。
executor 从未调用 onCancel(),导致取消标志始终为 false。
最终修复是先设标志,再在 task 内加入两个检查点。
展開詳細摘要
这篇文章拆解了短视频 SDK 中一个上传取消误报成功的缺陷:用户点击取消后,界面先停留在处理中,随后却被当成已成功发布,直到刷新才消失。根因来自两处静默失误:executor 只中断了线程,却没有先设置取消标志;而上传库在轮询时吞掉了中断异常,使流程正常返回。由于任务路由只依据标志判断,最终走到了成功分支。实际上线的修补很小:先设置标志,再在进度回调和 upload() 返回后各增加一次检查。文章还解释了为什么测试没有覆盖到这个问题,以及更大的同步取消 API 为什么最终被删除。
一個旗標、兩道檢查點:被取消的上傳如何回報成功
被取消的上傳之所以被判定為成功,是因為兩個無聲的失誤在錯誤時刻同時發生。
重點摘要
中斷只是請求,不是保證;若例外被吞掉,取消就會失效。
executor 從未呼叫 onCancel(),導致取消旗標一直是 false。
最終修補先設旗標,再在 task 內加上兩道檢查點。
展開詳細摘要
這篇文章剖析一個短影音 SDK 的取消上傳錯誤:使用者按下取消後,畫面先顯示處理中,之後卻被誤判為成功上傳,留下只有重新整理才會消失的幽靈項目。根因有兩處:executor 只中斷執行緒,卻沒有先設定取消旗標;而上傳函式庫在輪詢時吞掉了中斷例外,讓流程正常返回。由於路由只看旗標,task 最終走到成功分支。真正上線的修補很小,只是先設旗標,並在進度回呼與 upload() 返回後各做一次檢查。文章也說明為何測試沒抓到,以及較大的同步取消 API 最後被移除。
Memory allocation data revealed what the Layout Inspector was hiding about Compose recompositions.
重點摘要
Layout Inspector underreported work that the memory profiler exposed.
Unstable data classes, lists, lambdas, and missing keys drove extra churn.
@Immutable, ImmutableList, remember, and better list keys reduced allocations.
展開詳細摘要
A Compose screen that looked calm in Android Studio’s Layout Inspector was doing far more work than expected. By inspecting memory allocations, the author found thousands of object creations tied to recomposition internals such as recomposeToGroupEnd and ComposableLambdaImpl. The root causes were unstable data classes, interface-based lists, repeatedly recreated annotated strings, unstable lambdas, missing list keys, and an unnecessary wrapper composable. After adding @Immutable, switching to ImmutableList, using remember, stabilizing callbacks, and simplifying the hierarchy, allocations dropped sharply. The main lesson is that recomposition counts alone can be misleading; allocation profiling reveals hidden work that the Layout Inspector may not show.
My Journey Making Compose Multiplatform Work on tvOS, and What I Learned
ProAndroidDev作者:Sajid Ali發布:09-09 01:13
My Journey Making Compose Multiplatform Work on tvOS, and What I Learned
This series is about how that requirement ended with me maintaining a fork of Compose Multiplatform with tvOS support, and what I learned along the way.
重點摘要
Compose Multiplatform was chosen to avoid maintaining separate UI layers across mobile, TV, desktop, iOS, and tvOS.
SwiftUI’s focus management could not match the Android TV behavior the team already had, so tvOS support in Compose became the goal.
The port required changes in the Gradle plugin, runtime modules, and tvOS-specific input, focus, and rendering support.
展開詳細摘要
This post gives a high-level account of how a streaming app team ended up maintaining a fork of Compose Multiplatform with tvOS support. The author explains the app’s path from Android Views to Jetpack Compose and then to Compose Multiplatform, driven by the need to share UI across Android, desktop, iOS, and tvOS. A SwiftUI approach for Apple TV was tested but abandoned because its focus handling could not match Android TV behavior. The post outlines what tvOS is, why Kotlin Multiplatform targets made the port substantial, and how the work was split across the Gradle plugin and runtime modules. It also describes the module-by-module porting order, the shared uiKitMain source set, and the hardest parts of the effort: input, focus, rendering, and keeping up with upstream changes.
Forget the “Setup Tax”: A Production-Ready Multi-Module Android Template
ProAndroidDev作者:Shamil Gulmetov發布:09-09 01:34
Forget the Setup Tax: A Production-Ready Multi-Module Android Template
A clean, production-ready starter kit that extracts NiA’s best architectural patterns into an isolated foundation.
重點摘要
Uses multi-module architecture with shared core, feature, build-logic, and lint modules
Centralizes Gradle convention plugins, Compose setup, flavors, and coverage configuration
Adds custom lint rules, state helpers, design-system tokens, and an automated rename script
展開詳細摘要
This article presents a production-ready Android template that removes the repetitive setup work often required before application development begins. Inspired by Google’s Now in Android repository, it separates concerns into a feature-based multi-module structure, centralizes build logic with Kotlin convention plugins, and enforces architecture and design standards with custom lint checks. It also provides reusable Flow and StateFlow helpers, an isolated design system, and Hilt-based dispatcher and scope management. To make onboarding faster, the repository includes an automation script that renames the package and branding from a single terminal command, helping teams start new projects with less boilerplate and fewer setup errors.
The Android Startup Pattern: A Lifecycle-Aware, Multi-Module Approach
ProAndroidDev作者:Ehab Elwan發布:09-13 05:31
The Android Startup Pattern: A Lifecycle-Aware, Multi-Module Approach
A clean, DI-driven architecture for managing cold starts, background wakeups, and privacy compliance in modern Android apps.
重點摘要
Use multi-binding to collect startup tasks from feature modules into one injected set.
Separate cold-start, foreground, and session work with explicit phases and lifecycle-aware orchestrators.
Keep startup tasks idempotent, main-safe, and consent-aware to support retries and privacy rules.
展開詳細摘要
This article proposes a DI-driven Android startup pattern that replaces the common “God Class” split between Application and ViewModel startup logic. It recommends using multi-binding to let feature modules contribute startup tasks into a global set, then executing them through phase-based orchestrators for cold start, foreground, and session lifecycles. The design emphasizes idempotency, main-safety, and structured error handling so retries are safe and non-critical failures do not crash the app. It also explains why Jetpack App Startup is useful for raw framework initialization but unsuitable for app-specific logic that depends on DI or user consent. Finally, it advocates lifecycle-aware UI loading and lazy screen data fetching to reduce flicker, battery drain, and test complexity.
Android 启动模式:一种具备生命周期感知的多模块方案
以 DI 为核心的清晰架构,用于管理冷启动、后台唤醒和现代 Android 应用的隐私合规。
重點摘要
通过多重绑定汇聚各模块的启动任务,由主应用统一执行。
按冷启动、前台和会话状态拆分任务,并交由对应生命周期驱动。
任务必须具备幂等、主线程安全和同意状态感知,才能安全重试并满足隐私要求。
展開詳細摘要
本文提出一种由 DI 驱动的 Android 启动方案,用多重绑定把各功能模块的启动任务汇集到统一集合,再由分阶段的 orchestrator 按冷启动、前台和用户登录状态执行。作者强调任务应当幂等、主线程安全,并通过统一的错误处理区分致命与非致命失败,使重试不会重复破坏已完成的工作。文章也说明 Jetpack App Startup 适合处理原生框架初始化,但不适合依赖 DI 或用户同意的业务逻辑。最后建议 UI 以生命周期感知方式观察启动状态,并让页面数据按需加载,以减少闪烁、耗电和测试复杂度。
Android 啟動模式:具備生命週期感知的多模組作法
以 DI 為核心的乾淨架構,用來處理冷啟動、背景喚醒與現代 Android App 的隱私合規。
重點摘要
透過多重繫結匯集各模組的啟動任務,由主應用統一排程。
依冷啟動、前景與登入狀態拆分任務,並以相應生命週期驅動。
任務需具備冪等、主執行緒安全與同意狀態感知,才能安全重試與符合隱私要求。
展開詳細摘要
本文提出一種以 DI 驅動的 Android 啟動模式,用多重繫結把各功能模組的啟動任務匯入同一集合,再由分階段的 orchestrator 依冷啟動、前景與使用者登入狀態執行。作者強調任務必須冪等、主執行緒安全,並以一致的錯誤處理機制區分致命與非致命失敗,讓重試不會重複破壞已完成的工作。文中也說明 Jetpack App Startup 適合處理原生框架初始化,但不適合依賴 DI 或使用者同意的業務邏輯。最後建議 UI 以生命週期感知方式觀察啟動狀態,並讓畫面資料延遲載入,以降低閃爍、耗電與測試複雜度。
The “Downcast Trap” in Kotlin’s Explicit Backing Fields
ProAndroidDev作者:Ehab Elwan發布:09-13 05:31
The “Downcast Trap” in Kotlin’s Explicit Backing Fields
Explicit Backing Fields keep code cleaner, but they replace a physical wrapper boundary with a simple type restriction.
重點摘要
Old wrappers like .asStateFlow() create a defensive object boundary.
Explicit Backing Fields avoid the wrapper but rely on upcasting.
A malicious downcast can mutate internal state unless you trust the caller.
展開詳細摘要
This article compares Kotlin’s traditional double-property pattern with Explicit Backing Fields. The old approach uses a private MutableStateFlow plus a public StateFlow wrapper, which adds a small allocation but creates a strong architectural boundary. Explicit Backing Fields remove the wrapper and make the code cleaner, but the underlying object is still mutable. That means an external consumer can downcast the public reference back to MutableStateFlow and change internal state. The author argues this is usually acceptable for application code, since the same tradeoff exists with Kotlin collections and teams should rely on code reviews and static analysis. However, for public libraries or closed-source SDKs, defensive wrappers remain the safer choice.
I Counted Every Hidden Channel Kotlin Flow Creates — Most Devs Are Wrong About Which Operators Are…
ProAndroidDev作者:Majidshahbaz發布:09-13 05:43
I Counted Every Hidden Channel Kotlin Flow Creates — Most Developers Are Wrong About Which Operators Break Fusion
buffer() and flowOn() really do fuse — but only until an ordinary operator gets in the way.
重點摘要
Kotlin Flow fuses adjacent channelFlow, flowOn, buffer, and produceIn into one channel via FusibleFlow.
map(), catch(), onEach(), and distinctUntilChanged() break fusion; conflate() stays fused.
Breaking fusion adds wrapper objects, extra coroutines, and more dispatcher hops.
展開詳細摘要
The article tests a common Kotlin Flow belief: that buffer() and flowOn() fuse into a single channel. By instrumenting runtime behavior instead of relying on folklore, the author shows that fusion is real but fragile. Adjacent fusible operators share one underlying channel through FusibleFlow, yet inserting ordinary operators such as map(), catch(), onEach(), or distinctUntilChanged() breaks that chain. Measurements using reflection, coroutine debug dumps, and custom dispatcher logging show extra wrapper objects, an additional coroutine, and more thread hops when fusion is interrupted. conflate() is the exception because it is implemented as a form of buffer(). The practical advice is to group fusible operators together and not assume simple-looking transforms are free, especially in high-throughput pipelines.
How We Cut Our Android App Size by 82%: From 100+ MB to 17.76 MB
Medium Kotlin作者:Mahabub Karim發布:09-13 08:21
How We Cut Our Android App Size by 82%: From 100+ MB to 17.76 MB
A practical deep dive into APK analysis, R8, native dependencies, ABI duplication, and Compose Multiplatform.
重點摘要
APK analysis is used to identify major size contributors.
The article discusses R8, native dependencies, and ABI duplication.
Compose Multiplatform is part of the optimization discussion.
展開詳細摘要
This article promises a practical deep dive into how an Android app’s size was reduced by 82%, shrinking from more than 100 MB to 17.76 MB. It focuses on APK analysis and the kinds of factors that commonly inflate app size, including R8, native dependencies, ABI duplication, and Compose Multiplatform. Based on the available text, the piece is positioned as a technical walkthrough rather than a high-level overview, with an emphasis on understanding where the bloat came from and how it was addressed.
From One Encryption Scheme to Many: Designing a Versioned Encryption Layer on Android
Medium Kotlin作者:Jevi Saputra發布:09-13 08:26
From One Encryption Scheme to Many: Designing a Versioned Encryption Layer on Android
Designing a versioned encryption layer on Android to support multiple schemes, backward compatibility, and safer migrations.
重點摘要
Supports multiple encryption schemes
Preserves backward compatibility
Aims for safer migration between versions
展開詳細摘要
This article introduces the idea of designing a versioned encryption layer on Android so an app can support multiple encryption schemes over time. The goal is to make migrations safer while preserving backward compatibility, rather than forcing a single scheme for all data. The provided text is only a brief excerpt, so it does not include implementation details, performance claims, or specific Kotlin techniques.
Certificate Pinning in 2026: Rotating Pins Without Bricking Your App
Medium Kotlin作者:Alim Reshitov發布:09-13 08:41
Certificate Pinning in 2026: Rotating Pins Without Bricking Your App
Network Security Config, OkHttp, and the rotation runway most pinning tutorials never mention
重點摘要
Covers certificate pinning in the context of 2026
Focuses on rotating pins without breaking the app
Mentions Network Security Config and OkHttp
展開詳細摘要
This article frames certificate pinning for 2026 and highlights a practical concern many tutorials leave out: how to rotate pins without breaking an app. It points to Network Security Config and OkHttp as the relevant Android mechanisms, and emphasizes the need for a rotation runway rather than treating pinning as a one-time setup. The piece is presented as guidance on managing pin changes safely while preserving app connectivity.
Make coroutine stack traces great (and informative) again
Medium Kotlin作者:Roman Andrushchenko發布:09-13 10:57
Make Coroutine Stack Traces Great (and Informative) Again
Stack trace recovery is off by default on Android.
重點摘要
Stack trace recovery is disabled by default on Android.
The article explains how to turn it on.
It also points out traps that can silently disable it.
展開詳細摘要
The article focuses on coroutine stack trace recovery in Android. It explains that this feature is disabled by default, then describes how to enable it so coroutine failures become easier to understand. It also warns about subtle pitfalls that can silently take stack trace recovery away, making debugging less informative than expected.
JetImagePicker: Effortless Image Picking in Jetpack Compose (With Zero Permission Worries)…
Medium Kotlin作者:Nyerhovwo Adjekughene (Nerojust)發布:09-13 13:35
JetImagePicker: Effortless Image Picking in Jetpack Compose
This article covers JetImagePicker v2.0.0+, which has evolved significantly from v1 with major improvements to permissions handling.
重點摘要
Covers JetImagePicker v2.0.0+
The library has evolved significantly from v1
Major improvements were made to permissions handling
展開詳細摘要
This article introduces JetImagePicker v2.0.0+ and notes that the library has changed significantly since version 1. The main emphasis is on improved permissions handling, positioning the update as a more streamlined image-picking experience in Jetpack Compose. The excerpt does not add implementation details beyond this version note and the focus on permission-related improvements.
Kotlin vs Java in 2026: A 17-Year Java Developer’s Honest Take
Medium Kotlin作者:Anupam Sinha發布:09-13 14:57
Kotlin vs Java in 2026: A 17-Year Java Developer’s Honest Take
A practical comparison of where each genuinely wins, where Java has caught up, and how to choose.
重點摘要
A practical, non-fanboy comparison of Kotlin and Java
Focuses on where each language genuinely wins
Examines where Java has caught up and how to choose
展開詳細摘要
This article sets up a practical, non-biased comparison between Kotlin and Java in 2026 from the perspective of a developer with 17 years of Java experience. Rather than promoting one language as universally better, it aims to identify where each language has real strengths, where Java has closed gaps, and how developers can decide based on actual needs. The excerpt does not provide technical benchmarks or feature claims, so the piece should be read as a balanced opinion on choosing between the two languages rather than a definitive performance analysis.
I Counted Every Hidden Channel Kotlin Flow Creates — Most Devs Are Wrong About Which Operators Are…
Medium Kotlin作者:Majidshahbaz發布:09-13 05:43
I Counted Every Hidden Channel Kotlin Flow Creates — Most Devs Are Wrong About Which Operators Are...
buffer() and flowOn() are supposed to fuse into one channel when chained.
重點摘要
The author investigated hidden channels created by Kotlin Flow operators.
buffer() and flowOn() are expected to fuse into a single channel when combined.
The experiment uncovered four seemingly harmless cases that challenged common assumptions.
展開詳細摘要
The article examines how many hidden channels Kotlin Flow creates and questions common beliefs about operator behavior. The author specifically tests the idea that buffer() and flowOn() fuse into one channel when chained, then uses code to verify the actual behavior. During that investigation, four seemingly harmless cases surfaced, showing that many developers may misunderstand which operators create channels and how they interact.
JetBrains has released Kotlin 2.4.20, while the issue highlights new work across Compose, Ktor, AI tooling, Android, and libraries.
重點摘要
Kotlin 2.4.20 has been released by JetBrains.
Shopify says native is now the future of mobile, moving back from React Native to Swift and Kotlin.
The issue covers Compose, Ktor, RevenueCat, Google Gen AI SDK for Kotlin, Android, videos, and new libraries.
展開詳細摘要
Kotlin Weekly #528, dated 13 September 2026, rounds up the latest Kotlin ecosystem news, articles, videos, and libraries. The headline news is the release of Kotlin 2.4.20 by JetBrains, alongside Shopify’s shift back from React Native to Swift and Kotlin for mobile development. Article picks include Compose Desktop Native, JWT-based user management with Ktor and Exposed, offline support for Compose Web, RevenueCat integration for Kotlin Multiplatform, and the new Google Gen AI SDK for Kotlin. The issue also spotlights Android paywall animation work, several conference-style videos, and new libraries such as ARTEMIS and Library Insight.