Flutter跨平台开发鸿蒙应用:日期计算器实战指南

最近好几个做移动端的朋友问我同一个问题:已经把手头的 Flutter 技术栈学得差不多了,突然发现身边的团队都在转向鸿蒙,要不要跟着学一套新语言、新框架?

我的回答是:不用急着推倒重来。Flutter 这套跨平台方案,现在跑鸿蒙也是完全可行的。为了验证完整链路,我用一个很小的应用做了实战——日期计算器。别小看这个小工具,它麻雀虽小五脏俱全:日期选择、状态管理、算法边界、UI 布局、平台适配,能串起一条完整的跨平台开发主线。

这篇文章就把整个开发过程摊开讲,从环境搭建到核心算法,从界面交互到鸿蒙打包运行,再到我在真机调试中踩过的坑。不管你是刚接触 Flutter 的初学者,还是准备把老项目迁到鸿蒙生态的开发者,都能从里面找到可以直接抄作业的内容。

1. 项目切入点:为什么用 Flutter 做鸿蒙开发

1.1 鸿蒙开发的现实矛盾与跨平台破局

鸿蒙生态现在覆盖了手机、平板、智能座舱、IoT 设备,设备数量一路上涨,开发者的机会确实变多了。但摆在我们面前有一个非常现实的问题:如果每个新的生态都要求你用一套全新语言、全新 UI 体系从零开发,那学习成本和维护成本会高得吓人。

拿鸿蒙传统原生开发来说,需要掌握 ArkTS 语言和 ArkUI 声明式框架。这套东西本身设计得不错,但它和前端、Android 背景的技术栈差异比较大,学习曲线陡峭。很多团队手头已经积累了成熟的 Flutter 业务代码,让他们完全重写一遍,无论从工期还是风险角度都很难接受。

跨平台方案的价值就在这:一套 Dart 代码,同时产出 Android、iOS、HarmonyOS、Web、Windows 等多个平台的产物。业务逻辑、UI 组件、状态管理这些核心资产只需要维护一份。对个人开发者来说,这能让你用一份技能吃遍多个生态;对团队来说,这是降低多端维护成本最直接的方式。

1.2 Flutter 相比其他多端框架的优势

可能有人会问,跨平台方案也不是只有 Flutter 一家,为什么偏偏选它来做鸿蒙开发?

先看渲染方式。Flutter 用的是自绘引擎,UI 组件不是调用系统原生的控件,而是自己用 GPU 把每一帧画出来。这意味着在不同系统上,它的 UI 一致性和渲染性能都非常稳定。HarmonyOS 上的控件风格和 Android 不完全一样,如果你用某些依赖系统控件映射的方案,很容易出现按钮变大、列表卡顿、弹窗样式错乱的情况。Flutter 把渲染牢牢抓在自己手里,跨端表现差异就小得多。

其次看生态成熟度。Flutter 有非常完善的第三方包体系、热重载开发体验、成熟的性能分析工具,这些在鸿蒙原生开发里要么没有,要么还在成长中。对已经习惯 Flutter 工作流的开发者来说,迁移成本低,产出效率高。

再一点是代码复用率。日期计算器里会用到的日期处理逻辑、运算算法、状态管理,这些纯 Dart 代码几乎是零修改在 Android 和 HarmonyOS 上同时跑。这种复用率在整个项目层面意味着:你可以把业务核心沉淀为跨端资产,平台壳子交给 Flutter 去处理。这也是我推荐 Flutter 作为鸿蒙开发切入点的核心原因。

1.3 为什么教程 Demo 偏偏选日期计算器

选日期计算器做教程项目,不是因为它是 Hello World 级别的玩具,而是因为它在复杂度上刚好卡在了一个很合适的位置。

首先,它功能边界清晰。用户输入两个日期,系统算出相隔天数;或者输入一个日期加一个天数,系统推算出新日期。算是一个典型的有明确输入输出、有核心算法、有 UI 交互的小型应用。

其次,它覆盖的知识点很完整。日期选择控件的使用、日期转换与格式化、状态联动更新、平台默认样式的差异处理、边界条件的测试,这些内容全都能在一二百行代码里体现出来。把这些东西吃透,你再去写任何表单类、工具类应用都会顺畅很多。

另外,日期计算本身隐藏着不少算法坑。月份天数不一样、闰年判断、跨年处理、输入合法性校验,每个坑都特别适合用来讲透“程序员的日期素养”。我见过不少项目上线后被用户发现“日期差一天”“闰年算错”这类尴尬问题,早期用这个小 Demo 把边界逻辑练扎实,后面能避免很多线上事故。

2. 环境准备与工程搭建

2.1 Flutter 与鸿蒙 SDK 环境准备

在写代码之前,先把环境理顺。我这里按我实际操作的顺序来讲,新环境照这个走基本不会卡壳。

第一步,安装 Flutter SDK。要注意的一点是:鸿蒙适配需要用到包含 ohos 支持的分支,并不是官方主分支开箱即用。建议直接使用鸿蒙生态官方渠道维护的 Flutter 版本,安装时把对应厂库地址加到 Flutter 的依赖配置里,拉下来后切换到你需要的分支。

第二步,配置 Dart 语言环境。Flutter SDK 自带 Dart,所以装好 Flutter 之后 Dart 也就有了,不需要单独安装。命令行里敲flutter doctor,确认 Flutter、Dart、Android toolchain 都是就绪状态。我这边第一次跑doctor的时候,提示 Android licenses 未接受,按提示敲一遍flutter doctor --android-licenses输入 y 接受即可。

第三步,安装鸿蒙开发所需的 IDE 和 SDK。官方 IDE 装好之后,在 SDK Manager 里选择你需要的 API 版本,下载鸿蒙 SDK。这里有个小建议:API 版本不要盲目选最高,选你目标设备最低支持版本稍高一点就行,因为某些新 API 在老设备上没有对应实现,选太高反而增加打包体积和兼容负担。

第四步,把 IDE 的 SDK 路径配置到本地环境变量里。很多新手在这一步栽跟头:IDE 里能编译,但命令行一跑构建就报 SDK 找不到。原因很简单,工程构建时是通过环境变量去找鸿蒙 SDK 的,而 IDE 内部配置的路径并不会同步给命令行。把路径写进 shell 配置文件之后记得source一下,再重新打开终端验证。

2.2 创建项目与接入鸿蒙工程目录

环境就绪之后,创建项目就很快了。用 Flutter 自带的脚手架创建:

flutter create date_calculator

这里建议项目名全部用小写加下划线,不要用驼峰命名,否则后面打 Android 包时会有命名冲突。

创建完成之后,目录里默认有lib/、android/、ios/、web/等平台工程。接入鸿蒙时,需要把鸿蒙工程目录补进来。通常的做法是使用官方适配工具生成ohos/目录,或者直接拷贝鸿蒙空工程的配置改造成 entr y。

需要注意一个细节:鸿蒙工程和 Android 工程在构建体系上完全不同。Android 用 Gradle,鸿蒙用自家构建工具。所以不要试着把android/目录改改就塞给鸿蒙,老老实实走独立目录,两边构建互不干扰。我用官方工具生成ohos/配置后,工程根目录的pubspec.yaml不需要额外修改,依赖照常声明,Flutter 会在构建鸿蒙产物时自动处理 Dart 代码的编入。

2.3 编写前先想清楚三件事

环境搭好后别急着猛敲代码,我习惯先想三件事,能省不少返工时间。

第一,应用的数据模型是什么。日期计算器表面上操作的是“日期”,但内部到底是用字符串、时间戳,还是自定义的日期对象?字符串最适合展示但不适合计算,时间戳适合计算但是格式化麻烦。我的选择是内部统一用DateTime对象,只在输入输出层面做转换。

第二,状态管理用什么。小 Demo 不需要引入重型的状态管理框架,用 Flutter 自带的StatefulWidget加setState就完全够用。等后续扩展成工具集,再按需引入更复杂的状态管理方案。过早抽象是新手很容易犯的毛病。

第三,平台差异会让哪个环节出问题。比如日期选择控件在不同系统上的风格差异、时间格式的本地化差异、日期解析在某些平台上对 “2024-2-30” 这种非法日期的宽容程度不一样。想清楚这些,后面写代码时就知道哪些位置要加保护逻辑。

3. 日期计算核心逻辑

3.1 需求层:日期计算器要算哪些东西

开始写代码前,先把需求定清楚。我这里定义的日期计算器支持两类核心计算:

第一类,日期间隔计算。用户选择开始日期和结束日期,程序输出两个日期间隔的天数。这里要注意的是“包含头尾”还是“不包含头尾”。例如从 1 月 1 日到 1 月 2 日,有的产品逻辑算 1 天,有的算 2 天。必须把这个规则定义清楚并在界面上明示给用户,否则就是隐性 Bug。

第二类,日期推算。用户选择一个基准日期,输入一个偏移量(正数表示往后,负数表示往前),程序输出推算后的新日期。这类需求很实用,比如算“今天是 2024-06-01,90 天后是几号”“上次保养日期是 2024-02-28,再过 180 天是哪天”。

另外,界面还需要展示“今天周几”这类衍生信息,以及一个辅助功能:用户直接选择“今天”作为基准日期。这些功能看似不起眼,但对提升工具应用的实用性帮助很大。

我把数据模型设计成:一个开始日期、一个结束日期、一个偏移天数、一个结果值。状态就四个字段,清晰简单。

3.2 算法层:天数差与日期偏移的稳写法

先讲天数差计算。很多新手第一反应是用DateTime.difference拿Duration,再除以一天的毫秒数:

final difference = end.difference(start).inDays;

这在大多数情况下能算出结果,但有一个隐患:如果你的设备时区恰好有夏令时切换,某一天只有 23 小时或 25 小时,inDays除出来的结果是会偏的。国内现在没有夏令时影响较小,但跨平台应用要考虑全球用户。

更稳妥的方式是先把日期转成“绝对天数”,再做减法。思路非常简单:选定一个历史上足够早的锚点日期,比如公历元年 1 月 1 日,分别算出两个日期距离锚点的天数,然后相减。这个方案跳过了时区、夏令时这些干扰因素,计算语义完全受我们控制。

锚点天数算法其实不复杂:

int daysFromEpoch(DateTime date) { final d = DateTime(date.year, date.month, date.day); final epoch = DateTime(1, 1, 1); return d.difference(epoch).inDays; }

这里我故意先把时分秒清零再计算,保证只按日期维度算。如果直接用原始DateTime算,万一用户在界面上选完日期后系统时间带了几小时时区偏移,difference结果就微妙地不对了。

日期偏移计算的逻辑更简单,Dart 的DateTime构造器会自动处理月份进位:

DateTime addDays(DateTime date, int days) { return DateTime(date.year, date.month, date.day + days); }

传入day + days时,如果超出一个月的天数,会直接进到下个月,连闰年也一并处理。比如 1 月 31 日加 30 天,结果是 3 月 2 日而不是 2 月 31 日,完全符合日期推算语义。

3.3 时间边界与陷阱

日期计算的边界问题真的是绕不开的,我做这个 Demo 时专门列了一份边界清单。

第一个坑是闰年。闰年判断规则有两层:能被 4 整除但不能被 100 整除,或者能被 400 整除。例如 2000 年是闰年,1900 年不是。你如果简化成“能被 4 整除就是闰年”,那 2100 年就会算错。我在写月份天数工具时,没有自己硬记规则表,而是直接借助 DateTime 来推算:

int daysInMonth(int year, int month) { final firstOfNextMonth = DateTime(year, month + 1, 1); final lastDay = DateTime(firstOfNextMonth.year, firstOfNextMonth.month, 0); return lastDay.day; }

这个写法有点取巧:把日期设置为下个月的第 0 天,Dart 会自动帮你回退到上个月最后一天,自然就包含闰年逻辑了。不用自己维护月份天数表和闰年判断代码,出错概率低很多。

第二个坑是非法日期输入。用户可能会输入 2 月 30 日,如果直接交给DateTime解析,有的平台会静默进位变成 3 月 2 日,有的平台直接抛异常。两种行为都很危险。我在输入层做了严格校验:年月日三个数必须构成合法日期,否则提示用户重新输入。

第三个坑是时区。前面提到过,计算天数差和格式化展示时,如果单纯依赖本地时区,在某些时区会看到日期偏移。最好的实践是:计算逻辑里全部用纯日期语义,不掺时间;只在需要显示年、月、日时,才把DateTime对象格式化。这样把计算域与展示域隔离,问题就控制住了。

4. 界面交互实现

4.1 页面骨架与控件布局

日期计算器这种工具类应用,界面不需要花哨,但信息层级一定要清楚。我采用的结构是自上而下的线性布局:

顶部是标题栏,中间是输入区,底部是结果区,整体的操作路径就是“选日期 → 点计算 → 看结果”。

输入区包含四个控件:开始日期选择框、结束日期选择框、基准日期选择框、偏移天数输入框。为了不让页面显得拥挤,我用卡片把“日期间隔计算”和“日期推算”两个功能分成两个模块。每个模块里放对应的选择框和结果展示区。

具体布局我用的是一个外层ListView,里面套两个Card,每个Card内部用Column排列内容。为什么用ListView而不是Column?因为当键盘弹出后,页面需要能滚动,ListView天然支持滑动,也方便适配小屏设备。

4.2 调用系统日期选择器

Flutter 里调用日期选择器用的是showDatePicker方法,默认会返回一个Future<DateTime?>。用户点击选择框时,我在点击事件里弹出选择器,用户选定后更新状态并刷新界面。

showDatePicker有一些参数值得注意。首先是locale参数,如果你不设置中文环境,日期选择器会显示英文月份,这对国内用户很不友好。设置方式是在应用入口配置localizationsDelegates和supportedLocales,然后在调用showDatePicker时指定locale: Locale('zh')。

其次,firstDate和lastDate是必填参数,代表可选日期范围。我设置的是 1900 年到 2100 年,既覆盖绝大数用户的实际需求,又避免用户选到离谱的日期。有的开发者嫌麻烦直接设成 1900-01-01 到 2100-12-31,但如果你做的是年龄计算器,上限设得太大反而会让用户选到一个根本不可能存在的生日,这种小细节后期也可以按场景优化。

如果希望用户能快速回到“今天”,可以在日期选择器弹出前,把初始时间设为DateTime.now(),用户一打开默认就定位到当月,不需要来回翻月份,体验会舒服不少。

4.3 状态联动与输入校验

界面和逻辑联动的核心是状态管理。我这里用一个StatefulWidget,内部维护几个状态字段:

  • DateTime startDate
  • DateTime endDate
  • DateTime baseDate
  • int offsetDays
  • String intervalResult
  • String shiftResult

每当用户修改任何一个输入,我都调用一个_calculateAll()方法重新计算两个结果字段并setState刷新。这样结果是“即时计算”的,用户不需要额外点“计算”按钮,交互更顺滑。

输入校验放在哪里做?我放在了_calculateAll()的入口处。偏移天数输入框使用TextEditingController,在变更事件里解析字符串为int,解析失败就把结果区显示为“请输入有效数字”,同时不会崩溃。这里我用int.tryParse而不是int.parse,就是为了避免非法输入直接抛异常。

日期输入框的校验逻辑要更细一点。虽然showDatePicker返回的都是合法日期,但考虑到以后可能扩展成手动输入日期,我还是在计算函数前加了一层_isValidDate校验,拦截非法数据进入算法层。核心原则是:界面层可以接收各种输入,算法层只接受经过校验的数据。

5. 完整串联:把计算器和界面合体

5.1 数据流动链路

把界面和逻辑合体之前,先理清数据流,我实际开发时脑子里有这么一条链路:

用户点击日期选择框 →showDatePicker返回新日期 → 更新对应状态字段 → 触发_calculateAll→ 传入核心计算函数 → 返回结果字符串 →setState刷新 UI。

这条链路看似简单,但要特别注意一点:不要在build方法里做计算。新手容易犯这个错误,直接在 build 里调用计算逻辑,每次界面刷新都重复计算,既浪费性能又容易因为隐藏的副作用导致界面错乱。计算逻辑应该放在事件回调里,build 只负责把已经算好的结果展示出来。

我在代码里把这两种计算分别封装成函数,然后统一由_recalculate()调用。这样每次输入变更,只需要重新算受影响的结果,不会互相干扰。

5.2 可复用的计算服务类

日期计算逻辑这部分,我强烈建议单独拆一个类,不要写在 Widget 里。虽然日期计算器只有两个核心函数,但拆出来之后,逻辑可以单测、可以复用、以后换 UI 也不用翻布局代码。我建了一个DateCalculator类,包含daysBetween、addDays、formatDate、weekdayName这些方法,全部是静态方法,无状态,调用方便。

拆类的另一个好处是,后续如果要做历史记录功能,可以直接对DateCalculator写测试用例。我在开发过程中就顺手补了闰年、跨年、负偏移这几组测试,跑一遍确认逻辑没问题,心里踏实不少。

5.3 真机/模拟器运行验证

代码写完之后,先在 Android 模拟器上跑一遍,再切鸿蒙侧验证。Flutter 的调试流程在两边基本一致:连上设备后执行flutter run,就能把应用安装到设备或模拟器上。

我在 Android 模拟器上验证了日期选择的弹出风格、键盘弹出时的页面滚动、结果即时刷新这三项核心体验。然后在鸿蒙侧跑同一套代码,发现大部分效果一致,但有一个差异值得说:鸿蒙设备上日期选择器的视觉样式和 Android 不同,这是因为系统控件的主题映射有差异。Flutter 的控件虽然是自绘的,但某些与系统交互的组件,比如日期选择器,还是会走系统平台通道,于是表现出来的风格就有区别。

遇到这类差异不用慌,跨平台开发本来就不是追求绝对一致,而是追求体验和功能的一致。如果对某个控件的视觉风格有强要求,可以针对平台写条件样式分支,后面我会细说。

6. 鸿蒙适配与跨平台工程化

6.1 鸿蒙工程打包构建流程

运行验证通过后,最后一步是打出鸿蒙的安装包。整个流程分三步:

第一步,在工程根目录执行 Flutter 的构建命令,把 Dart 代码编译成鸿蒙侧可加载的产物。具体命令取决于你使用的适配工具链,通常是在ohos/工程目录下用鸿蒙构建工具执行 assemble。构建完成后,产物会生成在ohos/下的 build 目录。

第二步,用官方 IDE 打开ohos/目录,配置签名信息。鸿蒙应用的安装包必须有签名才能装到真机上。和 Android 的 debug 签名不同,鸿蒙的签名在 IDE 里通过自动签名配置,首次配置会生成调试证书,用于真机调试足够。

第三步,执行打包生成 HAP 文件,这个文件就是鸿蒙的安装包格式。之后既可以通过 IDE 直接装到模拟器上,也可以把文件发给别人实测安装。

整个过程中,我发现最容易出错的动作是切换工具链后的缓存残留。当你从 Android 构建切回鸿蒙构建时,偶尔会遇到莫名其妙的编译报错,这时不要急着改代码,先执行清理命令清掉工程里的构建缓存,再重新构建,大概率能解决。

6.2 平台相关行为与条件编译

跨平台开发很核心的一点是:该统一的必须统一,该差异的必须差异化。有几种做法可以在 Flutter 里处理平台差异。

第一种是ThemeData层面的适配。通过ThemeData可以控制在各系统上组件的圆角、颜色、字体,让界面保持你自己的设计语言。我在日期计算器里给主色调、按钮风格做了统一配置,这样在 Android 和鸿蒙上打开应用,视觉观感是接近的。

第二种是条件导入。Dart 支持根据平台导入不同的实现文件,通过这种机制可以把“需要平台特定能力”的代码抽离出来。比如以后要读取鸿蒙的系统日历数据,就可以把“读取日历”的接口在公共层定义,在 Android 实现和鸿蒙实现里分别写调用代码,业务层只面对同一个接口。这是跨平台工程化的标准姿势,值得从这种小项目就开始养成。

第三种是Platform判断。在运行期用Platform.isAndroid、Platform.isIOS这类手段做小范围分支处理。比如某些控件在这个系统上有已知问题,我可以在代码里加一个条件判断,给不同的 padding 或者默认行为。不建议到处用这种分叉,但遇到确实绕不过的差异,该用就别含糊。

6.3 从 Demo 到工具集的迭代建议

日期计算器做顺手之后,你会自然想把它扩展成一个 “小工具集合应用”,毕竟一个 App 只放一个计算器有点浪费。我在迭代时总结了几个方向。

第一个方向是合并换算法则。同一个页面里可以切换“日期差”“日期推算”“年龄计算”“节日倒计时”多个 Tab,底层复用的还是DateCalculator那套核心逻辑,只是把展示层换个说法。这让工具类应用的功能密度提升不少,用户留存率也更好看。

第二个方向是增加历史记录。用户算过的日期结果本地保存起来,下次打开可以复用。Flutter 里用shared_preferences包就能非常简单地做 KV 存储。配合ListView展示历史记录,应用就从一个纯计算器变成了带辅助记忆的工具。

第三个方向是增加主题切换。工具类应用是最不需要花哨的,但也是最容易被用户“用完即走”的。加一个深色模式,成本极低,体验提升却非常明显。Flutter 的ThemeMode本身就支持跟随系统、浅色、深色三种模式,这比很多原生应用还方便。

7. 常见问题与排查技巧

7.1 编译与依赖问题

问题一:构建鸿蒙包时提示 SDK 路径找不到。

这个十有八九是环境变量没有配置到位。IDE 内部的 SDK 路径不会自动同步给命令行,需要手动把 SDK 路径写到 shell 配置文件里。配置完记得重新打开终端,或者执行source让配置生效。

问题二:模块名重复导致构建冲突。

在创建工程时用了驼峰命名,比如dateCalculator,生成 Android 工程时有时会触发模块名解析冲突。解决方案非常简单:一切都用下划线小写命名,无论是项目目录还是包名。

问题三:依赖包拉取超时。

日期计算器用了本地化相关的包,首次拉取时网络不稳定容易出现超时。建议配置稳定的依赖源,或者把依赖文件里的包源路径改为国内可访问的仓库地址。这类问题排查起来很简单,看到构建日志里卡在某个包下载基本就是它。

7.2 运行与界面问题

问题一:日期选择器显示英文。

没有配置本地化代理和语言支持才会出现。需要在应用根部把localizationsDelegates和supportedLocales加上,并在调用日期选择器时指定locale。

问题二:键盘弹起后页面被遮挡。

工具类应用里输入框会被软键盘顶上去或盖住。我通过Scaffold的resizeToAvoidBottomInset属性和外层ListView解决了这个问题。如果个别布局仍出现遮挡,可以再给输入框加一个padding,让键盘弹出后内容有缓冲空间。

问题三:热重载后界面没有变化。

Flutter 的热重载对setState逻辑的更新非常友好,但对一些构造方法的改动支持有限。遇到这种情况,直接全量重启应用,比在代码里猜原因快得多。

7.3 日期与本地化问题

问题一:天数计算结果偶尔差一天。

最常见的原因是日期初始化时没有清掉时分秒,导致difference计算时被时区干扰。解决办法是按照我前面讲的方式,先统一把日期归零再计算,或者干脆用纯日期语义的函数。

问题二:日期格式化在不同系统上结果不一致。

手动拼字符串虽然灵活,但很容易掉进月份天数和前导零的坑。建议使用DateFormat这类标准化格式化方案,并且固定好目标格式,不要在 UI 层到处散落 “2024-6-1” 这种格式字符串。

问题三:闰年边界计算错误。

如果你自己写了月份天数和闰年判断逻辑,建议对照公历规则认真梳理一遍。最稳妥的做法是直接用 DateTime 构造器自动处理,不要重复造轮子。

8. 写在最后:一点真实的使用体验

开发这个日期计算器 Demo 的过程中,我最深的一个体会是:跨平台开发的价值,不在于写出多漂亮的框架代码,而在于让你有底气去面对不断变化的技术生态。当鸿蒙生态热度持续上升时,与其焦虑要不要重学一遍原生开发,不如把已经掌握的 Flutter 能力平滑地迁移过去。

我也愿意多说一句:网上有很多关于“某某框架已死”“某某生态要凉”的争论,我实际做下来的感受是,工具本身没有绝对的优劣,关键看你的使用场景。Flutter 在跨 UI 能力的一致性、开发效率、生态成熟度上,目前仍然是非常稳妥的选择。日期计算器这个项目虽然小,但它把一条完整实用的技术路线跑通了,这个验证过程的价值远超代码本身。

最后分享一个实用的小技巧:在做这类工具类应用时,把“计算核心”和“界面呈现”彻底分离,哪怕只是一个很小的项目也值得这样做。这样当你从 Android 切到鸿蒙,从手机横跨到平板,业务逻辑几乎不用改动,真正需要处理的只有壳子层面的适配。这个习惯一旦养成,你会发现自己应对技术变迁的底气越来越足。

相关新闻

Supabase实战指南:从云服务到本地部署的PostgreSQL全栈后端

Supabase实战指南:从云服务到本地部署的PostgreSQL全栈后端

做全栈项目时&#xff0c;最让我上头的后端服务其实是Supabase&#xff1a;它把PostgreSQL、Auth、Realtime、存储和Edge Functions打包成一个平台&#xff0c;云服务和本地部署都能跑通&#xff0c;专门用来做原型和中小型项目几乎不用自己写后端。尤其是现在大家都在用AI编程…

2026/10/20 14:55:49 阅读更多 →
用Python深度学习实现墙体裂缝有无识别:完整项目实战指南

用Python深度学习实现墙体裂缝有无识别:完整项目实战指南

最近有好几个准备做毕业设计的同学来问我同一个题目&#xff1a;用Python和深度学习做墙体裂缝的有无识别。这个题目看着简单&#xff0c;实际上从数据准备到模型训练再到答辩演示&#xff0c;每一步都有讲究。我当初做这个题目的时候&#xff0c;走了一条弯路——一上来就找目…

2026/10/20 14:55:49 阅读更多 →
POI-TL合并多个Word文档:两条路线与5个常见坑的完整解法

POI-TL合并多个Word文档:两条路线与5个常见坑的完整解法

简介&#xff1a;面向Java后端开发与办公自动化实施人员&#xff0c;这份资源系统讲解如何借助POI-TL技术实现多个Word文档的快速合并。POI-TL是Apache POI的扩展&#xff0c;专门用于处理.docx格式&#xff0c;提供了模板化编程接口&#xff0c;支持占位符替换以及段落、表格的…

2026/10/20 14:55:49 阅读更多 →

最新新闻

TensorFlow鞋类识别实战:Fashion MNIST图像分类全流程

TensorFlow鞋类识别实战:Fashion MNIST图像分类全流程

前段时间重新整理之前的深度学习实验笔记&#xff0c;翻到鞋类识别&#xff08;Fashion MNIST&#xff09;这个项目时&#xff0c;觉得特别值得拿出来单独写一篇。原因很简单&#xff1a;很多人入门深度学习时&#xff0c;都会被建议先跑通手写数字识别&#xff08;MNIST&#…

2026/10/20 20:57:37 阅读更多 →
用AI辅助Kamailio路由排错:一场人机讨论实录与故障切换实践

用AI辅助Kamailio路由排错:一场人机讨论实录与故障切换实践

最近接手一套老的SIP通信平台&#xff0c;核心信令是Kamailio撑着。业务要新增一个较复杂的路由策略&#xff1a;同一个主叫号码&#xff0c;在不同时间段、针对不同被叫前缀&#xff0c;要分别走不同的网关&#xff1b;而其中一路网关做故障切换时&#xff0c;还要保证已经建立…

2026/10/20 20:57:37 阅读更多 →
LibVLC轻量级视频播放模块:嵌入C/C++工程的硬件解码方案

LibVLC轻量级视频播放模块:嵌入C/C++工程的硬件解码方案

简介&#xff1a;本资源是一份基于C/C与VLC开源库开发Windows视频播放器的完整工程实践包&#xff0c;面向具备基础C编程能力、希望掌握多媒体开发技能的中级开发者及高校课程设计学习者。资源聚焦于在Visual Studio 2022环境下集成libvlc实现视频加载、播放控制、窗口渲染等核…

2026/10/20 20:57:37 阅读更多 →
AI Agent创业团队如何配置一支高效的Harness Engineering团队

AI Agent创业团队如何配置一支高效的Harness Engineering团队

1. 为什么需要一支专门的Harness Engineering团队先从一个很现实的场景说起&#xff1a;你所在的创业团队花三个月做出了一个基于大模型的Agent产品Demo&#xff0c;演示给投资人看时效果炸裂&#xff0c;但真正进入客户试用阶段&#xff0c;问题接踵而来——模型给出正确意图却…

2026/10/20 20:57:37 阅读更多 →
视觉语言模型与RGB-D感知融合:三条进化主线与工程实践

视觉语言模型与RGB-D感知融合:三条进化主线与工程实践

1. 从 Transformer 到多模态感知的演进逻辑视觉语言模型和 RGB-D 感知这两个方向&#xff0c;过去几年基本是各走各的路。做 VLM 的人盯着图文对齐、指令跟随、视觉问答这些任务&#xff0c;做 RGB-D 的人则埋头于点云配准、深度补全、SLAM 建图。但最近一年&#xff0c;这两条…

2026/10/20 20:57:37 阅读更多 →
VTI介质地震波数值模拟:MATLAB实现与各向异性正演避坑指南

VTI介质地震波数值模拟:MATLAB实现与各向异性正演避坑指南

简介&#xff1a;这份资源面向地震勘探与地球物理方向的学习者和研究者&#xff0c;提供一套基于Matlab的VTI介质地震波场数值模拟程序&#xff0c;用于分析各向异性介质中地震波的传播规律。VTI介质在垂直与平行层理方向上纵波速度存在差异&#xff0c;是实际地壳中常见的各向…

2026/10/20 20:56:32 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →