在 Android 开发中很多人第一次接触 BLEBluetooth Low Energy时都会遇到一个共同的问题蓝牙连接非常不稳定。常见现象包括扫描不到设备可以扫描但连接失败刚连接成功就断开服务发现失败数据通信偶尔丢包某些手机正常某些手机异常很多开发者会简单地通过失败后立即重试来解决但在真实工程中这种方式往往会导致问题更加严重。本文从工程角度系统讲清楚Android BLE 稳定连接到底应该如何设计。一、BLE 不稳定的常见表现BLE 的问题其实主要集中在以下几类问题类型表现扫描不到设备扫描列表没有目标设备连接失败connectGatt()后连接失败连接成功马上断开onConnectionStateChange()很快断开服务发现失败discoverServices()没有成功数据通信异常写入失败、丢包、超时机型兼容问题不同手机表现不一致很多项目的问题其实并不是蓝牙本身而是连接流程设计不合理。二、BLE 连接完整流程BLE 的完整连接链路通常是扫描设备 ↓ 建立连接 connectGatt ↓ 连接成功 onConnectionStateChange ↓ 发现服务 discoverServices ↓ MTU 协商 requestMtu ↓ 开启通知 enableNotification ↓ 数据通信 ↓ 保活 / 重连如果某一步处理不好就会导致连接异常。三、BLE 不稳定的核心原因在实际项目中BLE 不稳定主要有以下几个根因。1 连接流程混乱很多项目会出现以下问题扫描还没停止就连接刚断开立刻重连多线程同时操作 GATTActivity 销毁但连接没释放BLE 对调用顺序非常敏感。错误流程示例扫描 → connect → discover → write → enableNotify 多线程同时执行正确流程应该是扫描 → 停止扫描 → connect → discover → mtu → notify → write 严格顺序执行2 GATT 操作没有串行化BLE 的 GATT 操作必须串行执行。以下操作都必须按顺序discoverServicesrequestMtureadCharacteristicwriteCharacteristicwriteDescriptorBLE 的工作模型其实是发起操作 ↓ 等待回调 ↓ 再发起下一个操作如果多个操作同时发起极容易导致回调丢失状态错乱操作失败3 重连策略粗暴很多代码会写成连接失败 → 立即重连 断开 → 立即重连这种方式的问题蓝牙栈状态更混乱外设拒绝连接功耗上升出现无限重连正确方式应该使用指数退避策略例如重试次数等待时间11秒22秒34秒48秒4 资源释放不完整Android BLE 有一个非常常见的坑断开连接后必须 close()很多代码只写gatt.disconnect()正确流程应该是disconnect()↓收到断开回调↓close()↓释放 GATT 对象否则很容易出现连接异常status 133无法再次连接5 设备端本身不稳定有时候问题并不在 App而是设备。例如广播间隔异常连接参数不合理设备电量不足固件 Bug信号弱因此调试时一定要区分手机问题 vs 设备问题四、BLE 稳定性的核心设计思想在实际工程中BLE 连接必须设计为一个连接管理系统。推荐的架构如下BleManager │ ├── ConnectionStateMachine ├── RetryPolicy ├── OperationQueue └── DeviceSession核心思想不要在页面里直接调用 BLE API。而是统一由连接管理器控制。五、建立 BLE 连接状态机BLE 连接应该有完整状态。示例sealed class BleConnectState { object Idle : BleConnectState() object Scanning : BleConnectState() object Connecting : BleConnectState() object Connected : BleConnectState() object ServiceDiscovered : BleConnectState() object Ready : BleConnectState() data class Disconnected(val reason: String) : BleConnectState() data class Failed(val code: Int) : BleConnectState() }这样可以清晰知道当前阶段正在连接服务发现完成已经 ready异常断开六、连接前必须停止扫描很多设备在扫描状态下连接会失败。推荐流程scanner.stopScan(scanCallback) delay(300) device.connectGatt(context, false, gattCallback)这一步在很多设备上能明显提升稳定性。七、不要滥用 autoConnect连接设备时常见 APIconnectGatt(context, autoConnect, callback)很多开发者会使用autoConnect true但在很多机型上会出现长时间无回调假连接重连不可控通常建议autoConnect false八、增加超时控制BLE 的 API 有时不会回调。例如discoverServiceswriteDescriptorrequestMtu因此需要增加超时机制。示例连接超时服务发现超时特征写入超时通知开启超时没有超时机制时BLE 很容易卡死在某一步。九、区分主动断开和异常断开系统必须区分两种断开用户主动断开点击断开 ↓ disconnect ↓ 不自动重连异常断开例如信号弱设备断电蓝牙异常这时才应该进入自动重连机制。十、日志一定要完整BLE 排查问题最重要的是日志。推荐日志内容[BLE] startScan [BLE] stopScan [BLE] connectGatt [BLE] onConnectionStateChange status0 newState2 [BLE] discoverServices [BLE] onServicesDiscovered status0 [BLE] requestMtu [BLE] onMtuChanged mtu247 [BLE] enableNotify [BLE] writeCharacteristic [BLE] disconnected status133同时记录手机型号Android版本设备RSSI设备固件版本这样才能定位机型问题。十一、BLE 稳定设计总结Android BLE 稳定连接的核心并不是如何连接设备。而是如何管理连接生命周期。关键设计点包括连接状态机GATT 操作串行化超时机制断开清理指数退避重连前后台生命周期管理协议 ACK 机制完整日志系统只要把这些基础设施搭建好BLE 的稳定性会提升非常明显。十二、系列文章本文是 BLE 系列的上篇。下一篇将会给出完整工程代码Android BLE 稳定连接管理器Kotlin版完整代码骨架包括BLE 状态机GATT 操作队列自动重连策略超时机制日志系统Kotlin 协程实现实现一个工业级 BLE 连接管理器。