React Native 与 Flutter 在 IoT APP 中怎么选
IoT App 选 React Native、Flutter 还是 uni-app?从 BLE 库、Android 12+ 蓝牙权限、iOS 拿不到 MAC、MTU 分包、热更新和小程序复用等技术点对比,附设备通信层的代码结构。

本文目录
很多 IoT APP 项目在立项时会先问一句,移动端到底选 React Native 还是 Flutter。问题本身没错,但真到交付阶段,决定项目顺不顺的,通常不是框架名字本身,更多是设备接入链路、联调节奏、页面复杂度、团队维护方式和后续版本安排。前面这些条件没看清,技术选型很容易变成一句口号,等到样机联调、协议调整和版本扩展一起压上来,成本就会一下子冒出来。
站内现有技术资料已经写明,多爱普目前移动端技术栈同时覆盖 React Native 与 Flutter,前者经验为 5年+,后者为 3年+,两者都用于跨平台移动应用开发,并支持 iOS 与 Android。对正在评估 IoT APP 的团队来说,这类信息真正有用的地方,不是看哪一个分值更高,重点是先确认自己的项目更适合哪一种交付节奏。
如果当前还在收需求,可以先把 物联网 APP 开发服务、智能水族设备 App 与云平台案例 和 常见问题 放在一起看。项目资料暂时不完整也没关系,先把设备类型、通信方式、目标用户和计划上线时间发到 联系我们,先把首期范围收住,后面的技术判断会轻松很多。
先别急着比框架,先把 IoT 项目的约束写出来
IoT APP 和普通内容型应用不太一样,移动端只是其中一层。前面连着设备协议、蓝牙或云端链路,后面还要接账号、告警、日志和后台服务。若项目里蓝牙扫描、设备绑定、状态订阅、弱网重试、OTA 或消息提醒占比很高,移动端方案就不能只看页面写起来顺不顺手,还得看联调时谁来兜底、问题出现时怎么排、后面新设备接进来会不会把已有结构拖乱。
所以在比较 React Native 和 Flutter 之前,建议先把几件事情写实。设备是蓝牙直连,还是通过 MQTT、HTTP 或网关中转;首期是以控制为主,还是要把报表、消息和角色权限一起放进来;团队后续准备长期维护一个双端产品,还是先把 MVP 尽快上线;硬件协议是否已经稳定,还是预计联调期间还会频繁调整。问题一旦落到纸面,很多选型分歧会自己缩小。
若你现在就在做蓝牙或智能硬件接入类项目,也可以顺手对照 蓝牙APP开发怎么做 和 智能硬件接入APP的完整流程。这两篇文章讨论的重点不在某个框架,核心还是设备链路和联调条件。实际项目里,框架选择通常就是顺着这些条件往下收出来的。
React Native 更适合什么情况
React Native 更常见的优势,往往出现在团队协作方式已经比较明确的时候。若项目本身就有 Web 前端、后台接口和较成熟的产品节奏,移动端需要频繁跟业务页面、运营模块、账号系统一起推进,React Native 往往更容易纳入同一套协作习惯。页面变更较多、需求迭代较快、需要和现有前端资源互相支撑时,这类安排通常会更顺。
这类项目在 IoT 里并不少见。比如设备控制只是首期入口,后面很快要补商城、会员、经销商、工单、统计报表或企业后台协同,移动端工作量并不都压在设备通信上。这时候项目最怕的是页面扩展快,联调窗口又短,团队还要同时兼顾多个端口。React Native 在这种交付节奏里,常常更容易和整体开发安排放在同一条线上。
但前提也很明确,设备接入层怎么处理、原生能力谁来接、异常链路谁负责兜住,要在立项时先说清。IoT APP 真正容易出问题的地方,经常不是首页和列表页,更多是蓝牙权限、系统后台切换、设备重连、状态订阅和不同机型兼容。要是这些部分本来就需要较多原生协作,选 React Native 也不代表能省掉这层工作。
Flutter 更适合什么情况
Flutter 更适合的,往往是另一类项目。若产品首期更看重统一交付、界面控制和一套代码稳定推进,设备侧范围也相对明确,Flutter 会更容易把页面、动效和交互节奏收得比较整。对于很多要尽快做出完整双端体验的项目来说,这会是一个实际优势,尤其是在产品逻辑集中、界面结构相对统一的时候。
IoT 场景里常见的一种情况是,首期重点非常聚焦,设备种类有限,控制流程固定,团队希望先把一个完整闭环跑通,再逐步扩版本。若当前需求主要围绕设备列表、状态展示、控制面板、告警提醒和少量后台协同展开,且页面风格、组件一致性和交付完整度被看得比较重,Flutter 通常更容易把首版收住。
同样要提醒的是,Flutter 也不是把技术问题自动抹平。协议不稳定、样机到位慢、蓝牙行为没定、云端接口反复改,这些问题换哪个框架都还是问题。IoT 项目里的风险,本来就更多在设备和业务边界,不在技术名词本身。前面要是把框架当成决定性答案,后面通常还是会回到联调和验收口径上。
我们的选择
我们的项目里没有用 Flutter。冷链 App、电动工具 App 和自研的 ChatBLE 用 React Native + Expo,BMS、灯具控制器和智能鱼缸用 uni-app,因为它能同时出 App 和微信小程序。蓝牙部分两边都要处理 Android 12 以上的新权限模型和 iOS 的差异。这是我们的经验,不代表 Flutter 不合适。更多见技术实力。
IoT App 的分层:框架差异集中在底层
IoT App 分层:页面层、状态与数据、设备通信抽象、原生能力、发布与更新
把一个 IoT App 拆开看,页面和状态管理用哪种框架都能做好;真正拉开差距的是原生能力(蓝牙、权限、后台)和发布更新方式(能不能热更新、能不能同时出小程序)。所以比框架之前,先列出设备通信需要的原生能力清单,再看哪个框架的生态更省事。
三种方案的技术差异
React Native、Flutter、uni-app 在 IoT App 中的关键差异对比
我们的生产项目主要用 React Native 和 uni-app,所以把 uni-app 也放进来一起比。三者都能交付稳定的 iOS / Android App,选型时重点看三件事:
- 蓝牙能力从哪里来:React Native 和 Flutter 依赖社区蓝牙库,版本升级时要跟进库的兼容性;uni-app 内置 BLE API,同一套接口在 App 和小程序上都能用。
- 能不能热更新:设备协议经常在联调期调整,React Native 可以通过 expo-updates 等方案更新 JS 包,修协议解析不用等商店审核;Flutter 官方没有代码热更新。
- 要不要小程序:要 App + 微信小程序一起交付,uni-app 基本是唯一能大量复用代码的方案。
设备通信层怎么写:先抽象再适配
不管选哪个框架,蓝牙、MQTT、HTTP 三种通道都建议收敛到同一个接口,页面只关心「发命令、拿结果」:
// 设备通信抽象:页面层不直接调用蓝牙库
export interface DeviceTransport {
connect(deviceId: string): Promise<void>
disconnect(): Promise<void>
// 发送一帧并等待匹配的应答,超时抛错
request(frame: Uint8Array, opts?: { timeoutMs?: number; retries?: number }): Promise<Uint8Array>
// 订阅设备主动上报
onNotify(handler: (frame: Uint8Array) => void): () => void
}
// 同一套协议编解码,蓝牙和 4G 远程共用
export const codec = {
encode: (cmd: number, payload: Uint8Array) => buildFrame(cmd, payload), // 帧头 + 长度 + 功能码 + 数据 + 校验
decode: (raw: Uint8Array) => parseFrame(raw),
}这样做的好处是:蓝牙近场和 4G 远程走同一套协议编解码,App 上不会出现两套数值;换蓝牙库或者换框架时,只需要重写 BleTransport 这一层。我们做电动工具 App 时,手机端和 Go 桌面端就是共用一套帧协议定义(帧头、长度、功能码、数据、异或校验、帧尾)。
跨平台蓝牙开发的几个硬坑
- Android 12 以上的权限模型变了:扫描要
BLUETOOTH_SCAN,连接要BLUETOOTH_CONNECT,旧版本还需要定位权限。权限请求流程和拒绝后的引导要单独设计,否则用户在部分机型上「扫不到设备」。 - iOS 拿不到 MAC 地址:CoreBluetooth 只给一个系统生成的 UUID,而且不同手机看到的 UUID 不一样。如果业务要按 MAC 或 SN 绑定,需要设备把 SN 放进广播数据或设备名里(例如「前缀 + SN」命名规则),App 按规则过滤。
- MTU 和分包:Android 需要主动请求更大的 MTU,iOS 由系统协商;单包可用长度通常是 MTU 减 3 字节。OTA 和批量读取记录都要按实际 MTU 分包,并逐包确认。
- 写入方式:
write with response可靠但慢,write without response快但可能丢包。我们在 BMS 项目里的做法是超时后自动切换写入方式重试,并把每次切换记进升级日志。 - Expo 项目的蓝牙:蓝牙库包含原生代码,不能在 Expo Go 里运行,需要使用 development build 或 prebuild。
框架之外更影响交付的东西
- 多语言:海外设备 App 动辄十几种语言,文案要从第一天就走 i18n 资源文件,我们做过 4 种、16 种、19 种语言的版本。
- 鸿蒙:国内 C 端产品要评估 HarmonyOS 原生版本,三种跨平台框架对它的支持程度都在变化,需要单独排期。
- 调试工具:蓝牙联调阶段,一个能看原始报文、能发 HEX 的调试工具能省大量时间,我们为此做了自研的 ChatBLE。
真正该怎么做判断
如果项目现在还在前期,没有必要把选型讨论拖成一场抽象辩论。更有效的做法,是先把移动端要承担的工作拆成几块看。第一块是设备接入,包含蓝牙、网关、MQTT 或云端通信;第二块是业务层,包含账号、角色、消息、报表和后台协同;第三块是交付节奏,包含样机状态、接口稳定度、版本计划和后续维护责任。三块放在一起,框架选择通常就不会太飘。
简单说,若项目和现有 Web 团队协作很深、业务页面变化频繁、后续还有较多运营或后台联动,React Native 往往更值得优先评估。若项目更强调一套双端体验尽快收口、设备范围相对稳定、首期目标偏控制闭环和产品完整度,Flutter 往往更适合先落地。两种方案都能做 IoT APP,差别主要在你希望把复杂度放在哪一段。
如果正在比较 React Native 与 Flutter,建议先整理设备清单、通信方式、首期功能、联调资料状态和上线时间,再通过 联系我们 获取技术选型建议。还在做第一轮判断的,也可以先对照 物联网 APP 开发服务、智能水族设备 App 与云平台案例 和 常见问题,看项目更接近哪一种交付方式。
常见问题
React Native 做蓝牙 App 用什么库?
常用 react-native-ble-plx 这类社区库,覆盖扫描、连接、读写和通知。使用 Expo 时需要 development build,不能在 Expo Go 里直接运行。
Flutter 做蓝牙 App 用什么库?
常用 flutter_blue_plus 等社区库。选库时重点看是否支持 MTU 请求、后台连接和最新的 Android 权限模型,并留意维护活跃度。
跨平台 App 能拿到蓝牙设备的 MAC 地址吗?
Android 可以,iOS 不行。iOS 只提供系统生成的 UUID,需要设备把 SN 或 MAC 放进广播数据、设备名或某个可读特征值里,App 才能稳定识别同一台设备。
既要 App 又要微信小程序,选哪个框架?
uni-app 更合适,同一套 Vue 代码可以编译成 App 和小程序,蓝牙 API 也基本一致。我们的 BMS、灯具控制器、智能鱼缸项目都是这样交付的。
IoT App 一定要做热更新吗?
不是必须,但联调期和上线初期很有用:协议解析、文案和小问题可以快速修复。涉及原生代码、权限和新功能的变更仍然要走商店审核。
已经用 Flutter 写了一半,还能接蓝牙和 MQTT 吗?
可以。框架本身不是瓶颈,关键是把设备通信抽象成独立模块,蓝牙、MQTT 分别实现并统一协议编解码。