Android BLE SDK 设计手册(一):一次参数改动,让我重新设计了整套架构

起因很蠢。

固件更新了配网协议,参数顺序改了一下:

scss 复制代码
// 之前
sendWifiConfig(ssid, password, qos, port, url)

// 之后
sendWifiConfig(ssid, url, password, port, qos, ...)

就这么一个调整,后续处理花了好几天:Android 改方法,iOS 同步跟上,项目逐个排查调用,Demo 页面重写,几个老项目直接崩了。

排查过程里我一直有个不舒服的感觉,但当时没想清楚。

后来才意识到------问题根本不在参数顺序,而在于我们的 SDK 设计,天然对这类变化没有抵抗力。

旧架构是什么样的

典型的方法调用模式:

scss 复制代码
sdk.sendWifiConfig(...)
sdk.queryDeviceInfo(...)
sdk.connect(...)

每个功能一个方法,清晰直接。早期完全够用。

但业务在三条线上同时增长:协议版本在叠加,设备型号在增加(单面屏、双面屏、多面屏、定制设备......),客户定制需求越来越多。

旧架构应对这些的方式只有一个:加方法。

于是 SDK 对外接口涨到了 99+,而且没有停的迹象。每次新增功能,要改的地方是一条链:协议适配层、设备逻辑层、对外 API、Android、iOS、Demo、文档------缺一不可。

维护成本越来越高,但每次交付的其实只是一个新方法。

重新想这件事

我花了一段时间想一个问题:为什么每次新需求都那么重?

结论是:功能被定义在了方法里。每增加一个能力,就必须增加一个入口。接口膨胀是必然的,不是偶然的。

如果把功能定义在协议里,情况会不一样。

于是我们做了一个方向上的调整:把 SDK 从"方法集合"改成"协议系统"。

对外只保留一个入口:

scss 复制代码
device.executeJson(jsonRequest, callback)

调用方描述"我要做什么":

json 复制代码
{
  "action": "wifi_set",
  "data": {
    "ssid": "OfficeWiFi",
    "password": "12345678"
  }
}

参数校验、协议转换、底层编码(byte / CBOR)、结果回调,全部在 SDK 内部处理。

请求和响应的格式

请求:

json 复制代码
{
  "action": "wifi_set",
  "data": {}
}

响应:

css 复制代码
{
  "code": 0,
  "data": {}
}

错误码统一:

code 说明
0 成功
10000 设备未连接
10001 Action 不支持
10002 参数无效
10003 请求失败/超时
10004 不支持字段

之前每个接口有自己的返回格式,联调的时候经常要对文档。现在统一了,省了不少沟通成本。

内部那层才是真正关键的

对外统一入口,只是表面。

真正的变化在 SDK 内部。

我们建了一个协议定义中心,用 JSON 描述每一个 action 的结构:

json 复制代码
{
  "mqtt_connection_set": {
    "commandType": "SET_MQTT_CONNECTION",
    "groupId": 1,
    "functionId": 1,
    "optionCode": 2,
    "requestParams": [
      { "name": "url", "type": "string", "required": true },
      { "name": "client_id", "type": "string", "required": true },
      { "name": "usrname", "type": "string", "required": true },
      { "name": "pwd", "type": "string", "required": true }
    ]
  }
}

这不是注释,也不是文档,是运行时实际读取的规则。

SDK 基于这份定义,自动完成参数校验(必填、类型、长度)、协议字段映射、编码生成、响应解析。

新增一个 action,不用改任何逻辑代码,加一段 JSON 配置就够了。

之前:

ini 复制代码
if (action == xxx) {
    // 写一堆处理逻辑
}

现在:

json 复制代码
{
  "new_action": { ... }
}

扩展方式从改代码变成加配置,这是这次重构真正想达到的。

迁移比设计难多了

新架构本身不复杂,想清楚之后画两天图就能出来。

难的是旧系统在线上跑着,几十个项目在用,不可能一刀切换。

我们的做法是:新项目直接用新架构,老项目维持原样,过渡期两套并存,等老项目自然迁移或有改动需求时再跟进。

这个过程比预期长,但没出什么大问题。

上线之后的变化

最明显的一点:开发流程变了。

以前是"提需求 → 各端分别加方法 → 联调",现在是"先定协议 JSON → 双端按协议实现 → SDK 处理中间层"。

Android 和 iOS 开发不再需要各自理解底层协议细节,只要对着同一份 JSON 定义写就行。沟通成本降了很多,联调时扯皮的情况也少了。

回头看这次重构,导火索是个参数顺序问题,但它暴露的是一个更早就存在的结构性问题:SDK 的扩展方式,决定了它能承受多大的变化。

方法式设计够用,但只是"够用"。当变化频率上来之后,维护成本会把你拖慢。

换成协议驱动之后,感受最深的不是什么架构上的优雅,而是:加新功能不再让我头疼了。

相关推荐
禅与计算机程序设计艺术9 分钟前
面向大语言模型智能体的 Harness 工程:工具编排、记忆与自修复闭环设计
架构
2601_962885729 分钟前
如何用 Python 判断一只股票“追涨”还是“抄底”更有效?
android·开发语言·python
素师良码9 分钟前
第10篇:屏ESD Check内核逻辑驱动代码完整拆解
android
高晶15 分钟前
Android 短信收发模块从零到实战:权限配置、界面设计、发送接收与兼容性适配全攻略
android·程序员
随遇丿而安18 分钟前
第18周:ViewModel 基础功能 + 架构优化
android
众链网络30 分钟前
从一次近 5 小时的大模型中断,讲清 AI 应用的降级设计
人工智能·架构
Thneonl39 分钟前
一次 rebalance,全组停摆:Kafka lag 从 0 到百万的事故复盘
后端·架构
anew___1 小时前
《从零手写操作系统 (48):网络协议栈基础——Socket API与TCP/IP分层架构》
网络协议·tcp/ip·架构
weixin_382395232 小时前
0-500 人工厂的生产 PMC 系统怎么做?基于 Tauri + SQLite 的性能架构实践与 5000 物料压测实录
数据库·架构·sqlite
软件工程师文艺2 小时前
制造业数字化转型路线图:从信息化总体规划到智能工厂的五阶段演进
架构