Flutter Stream 详解
Flutter 里用得极多的 Stream 其实是 Dart 语言(dart:async)提供的核心能力。理解它最好的切入点是和 Future 对比:Future 代表一个将来才有的异步值(比如一次网络请求的结果),而 Stream 代表一串随时间陆续到达的异步事件序列(比如点击流、传感器数据、WebSocket 消息)。 维度 Future<...
Flutter 里用得极多的 Stream 其实是 Dart 语言(dart:async)提供的核心能力。理解它最好的切入点是和 Future 对比:Future 代表一个将来才有的异步值(比如一次网络请求的结果),而 Stream 代表一串随时间陆续到达的异步事件序列(比如点击流、传感器数据、WebSocket 消息)。 维度 Future<...
Flutter 的 Channel(平台通道)是 Dart 层与原生平台(Android/iOS 等)之间通信的桥梁。因为 Flutter 的 UI 和业务逻辑都运行在独立的 Flutter 引擎里,想访问平台特有能力(电池、传感器、蓝牙、原生 SDK 等)就必须“跨界”通信,而 Channel 就是这套异步消息传递机制。 整体架构 消息的流动是这样的:Dart 侧发起调用 → 参数...
本文整理 Flutter 高频面试知识点,按「Dart 语言 → Widget 与三棵树 → 状态管理 → 渲染与布局 → 事件机制 → 线程与异步 → 混合开发 → 性能优化 → 引擎架构」的顺序组织,方便系统性复习。 一、Dart 语言基础 Dart 为什么适合 Flutter? JIT + AOT 双编译:开发期用 JIT(Just-In-Time)编译,支持 Hot R...
用 Claude Code 写 Android 项目大半年了,从最初”当高级搜索引擎用”,到现在日常开发的大部分编码工作都交给它,中间踩了不少坑,也攒了一套自己的工作流。这篇文章把这些心得系统整理一下:怎么描述需求才高效、Token 怎么省、缓存命中率是怎么回事、会话什么时候该重开、Agent / SubAgent / Hook / MCP 这些概念到底是什么、有哪些常用命令和隐藏功能、以及...
这篇是对近一年在一款企业级 IM / 协同办公 Android 客户端上做的几项架构改造的系统复盘。产品形态可以概括为「IM 即时通讯 + 音视频会议 + 组织架构 + 轻量办公套件(日历 / 文档 / 邮箱 / 待办)」,代码按「应用宿主层 → 业务插件层 → 通用组件层 → 基础能力层」分层,采用 Kotlin + Jetpack Compose + MVI。 下面每个专题都按「背景与...
在视频播放场景里,我们经常会遇到两类需求:一类是播放时尽量复用本地缓存,减少重复网络请求;另一类是当缓存已经足够完整时,将缓存内容导出成一个完整的视频文件,供离线使用或后续处理。 Media3 已经提供了缓存、下载、播放器接入等基础能力,但“把缓存导出为一个完整文件”这件事,仍然需要业务层做一次封装。本文结合一套可落地的实践方案,系统梳理以下两个问题: 本文偏「怎么实现」的完整代码...
Kotlin 协程中的 Dispatchers.IO 和 Dispatchers.Default 都是用于将协程分派到后台线程池执行任务的调度器,但它们针对的任务类型和底层线程池配置有着本质的区别,这对于保证应用程序的性能至关重要。 核心区别:任务类型和线程池配置 特征 Dispatchers.Default Dispatchers....
Kotlin 中的 inline、crossinline 和 noinline 是在处理 高阶函数 时非常重要的关键字,它们主要用于优化性能和控制 lambda 表达式中的非局部返回(non-local return)行为。 1. inline (内联) 概念解释 inline 关键字用于修饰函数。当一个函数被标记为 inline 时,编译器在编译时不会生成该函数的调用代码,而是...
For all those that had issues with “Your environment does not support JCEF, cannot use Markdown Editor”: this is because AndroidStudio by default uses a runtime that does not support JCEF. Here is ...
在 Jetpack Compose 中,Modifier 是构建和定制用户界面的核心。通过链式调用,开发者可以精确地控制可组合项 (Composable) 的外观和行为。本文档将深入解释 Modifier.wrapContentWidth(Alignment.Start, unbounded = false) 和 Modifier.weight(1f, fill = false) 这两个修饰...