杰理 SDK 文档中心
首页
首页
  • 项目概述

    • 杰理 OTA SDK 项目简介
    • 快速开始与接入指南
    • 工程结构与发布物
  • 核心库与依赖

    • OTA 核心库集成
    • 版本历史与更新说明
  • SDK 工具层

    • OTA 参数配置
    • 蓝牙扫描与连接管理
    • BLE 通道与事件回调
    • OTA 升级流程与状态模型
    • 固件文件管理与监听
  • 演示应用

    • 演示应用架构与主界面
    • 设备发现与连接界面
    • 文件选择与升级界面
    • 多设备 OTA 模型

BLE 通道与事件回调

本文档介绍 JL OTA Android SDK 中 com.jieli.otasdk.tool.ota.ble 包的 BLE 通道实现与事件回调体系:BleManager 负责 BLE 扫描、连接、服务发现、MTU 协商与数据收发;BleEventCallbackManager 负责将底层蓝牙事件统一分发给上层注册的 BleEventCallback 回调,构成 OTA 升级过程中设备通信的完整链路。

Purpose and Scope

本页聚焦于 BLE 通道(BleManager) 与 事件回调(BleEventCallbackManager / BleEventCallback / IBleEventCallback) 两大核心职责,覆盖:

  • BLE 通道的架构、生命周期与超时/重连机制;
  • 11 种 BLE 事件的定义、分发机制与设计意图;
  • 与通道相关的配置常量、消息码与数据模型(BleDevice、BleScanInfo、BleConnectParam、BleSendTask);
  • 数据发送线程(SendBleDataThread)与通道的协作关系;
  • 失败模式、并发与扩展点。

以下内容属于其他目录页,不在本页展开:

  • OTA 固件升级流程本身(如 UpgradeFragment、BroadcastBoxActivity)——参见 OTA 升级相关页面;
  • 文件监听工具(OtaFileObserver / OtaFileObserverHelper)——参见文件监听页面;
  • 全局配置(ConfigHelper)与多设备重连(ReConnectHelper)仅在本页作为依赖提及。

Overview

在 JL OTA SDK 中,BLE 通道是与设备(如蓝牙音箱、耳机等杰理芯片设备)进行数据传输的基础设施。OTA 升级包、指令帧与应答帧全部经由 BLE GATT 通道收发,因此通道的稳定性、超时处理与事件通知质量直接决定升级成功率。

整个通道层围绕两个核心类展开:

  1. BleManager —— 单例的 BLE 连接管理器。它封装了 Android BluetoothAdapter / BluetoothLeScanner / BluetoothGatt,对外提供扫描、连接、断开、MTU 协商、通知使能、数据发送等能力;内部使用主线程 Handler 驱动各类超时(扫描、连接、MTU、服务发现、断开等),并通过 ReConnectHelper 支持断线重连。
  2. BleEventCallbackManager —— 事件分发器。它继承 BaseCallbackHelper<BleEventCallback>,将底层 GATT 回调与系统广播(蓝牙开关、扫描状态等)转换为 11 种语义化事件,广播给所有已注册的 BleEventCallback 监听者。

事件回调采用 观察者模式 + 空实现适配器(BleEventCallback):调用方只需继承 BleEventCallback 并覆写关心的回调方法,无需实现全部接口方法;BleEventCallbackManager 通过 callbackEvent(...) 统一在回调线程遍历并通知所有注册者,屏蔽了 Android BLE 回调线程切换的复杂性。

Architecture

下图展示 BLE 通道层的整体架构:应用层通过 BleManager 与 Android 系统 BLE 栈交互,BleEventCallbackManager 作为事件枢纽向上层回调分发事件,数据模型层为各环节提供载体。

flowchart TD
    subgraph sg_App["应用层 (App / OTA SDK)"]
        App["App / UpgradeFragment / BroadcastBoxActivity"]
    end

    subgraph sg_Channel["BLE 通道层 com.jieli.otasdk.tool.ota.ble"]
        BM["BleManager<br/>(单例通道管理器)"]
        ECM["BleEventCallbackManager<br/>(事件回调分发器)"]
        SBDT["SendBleDataThread<br/>(串行发送线程)"]
        RCH["ReConnectHelper<br/>(断线重连辅助)"]
        BM -->|"驱动"| ECM
        BM -->|"投递发送任务"| SBDT
        BM -->|"断线重连"| RCH
    end

    subgraph sg_Callback["回调接口层 interfaces"]
        IBEC["IBleEventCallback<br/>(接口)"]
        BEC["BleEventCallback<br/>(空实现抽象类)"]
        OWDC["OnWriteDataCallback<br/>(写数据回调)"]
        IBEC <|-- BEC
        BEC ..->|"注册"| ECM
        OWDC ..-> SBDT
    end

    subgraph sg_Model["数据模型层 model"]
        BD["BleDevice"]
        BSI["BleScanInfo"]
        BCP["BleConnectParam"]
        BST["BleSendTask"]
    end

    subgraph sg_Android["Android 系统 BLE 栈"]
        BT["BluetoothAdapter / LeScanner"]
        GATT["BluetoothGatt / GattCallback"]
    end

    App -->|"connect / scan / send"| BM
    BM -->|"系统调用"| BT
    BM -->|"GATT 操作"| GATT
    GATT -->|"系统回调"| BM
    BM -->|"持有/使用"| BD
    BM -->|"扫描结果"| BSI
    BM -->|"连接参数"| BCP
    SBDT -->|"任务载荷"| BST
    ECM -->|"事件通知"| BEC

架构要点:

  • BleManager 是唯一的通道入口。应用层所有 BLE 操作都汇聚到它,它同时持有 BleEventCallbackManager、SendBleDataThread、ReConnectHelper,是通道层的"门面"(Facade)。
  • 事件流单向向上。BluetoothGattCallback 与系统 BroadcastReceiver 产生的原始事件,统一在 BleManager 内部转译为语义化事件后交给 BleEventCallbackManager,再由它广播给所有注册的 BleEventCallback,实现通道与业务解耦。
  • 数据流向下投递。上层发送数据时,BleManager 将 BleSendTask 放入 SendBleDataThread 串行发送队列,避免并发写 GATT 特征导致的丢包。
  • 数据模型是事件参数的载体。BleDevice(连接设备状态机)、BleScanInfo(扫描附加信息)、BleConnectParam(连接参数)作为回调参数贯穿整个事件体系。

事件回调体系

回调接口层次

事件回调采用三层设计,每一层都有明确职责:

classDiagram
    class IBleEventCallback {
        <<interface>>
        +onAdapterChange(boolean)
        +onDiscoveryBleChange(boolean)
        +onDiscoveryBle(BluetoothDevice, BleScanInfo)
        +onBleConnection(BluetoothDevice, int)
        +onBleServiceDiscovery(BluetoothDevice, int, List~BluetoothGattService~)
        +onBleNotificationStatus(BluetoothDevice, UUID, UUID, int)
        +onBleDataBlockChanged(BluetoothDevice, int, int)
        +onBleDataNotification(BluetoothDevice, UUID, UUID, byte[])
        +onBleWriteStatus(BluetoothDevice, UUID, UUID, byte[], int)
        +onConnectionUpdated(BluetoothDevice, int, int, int, int)
        +onSwitchBleDevice(BluetoothDevice)
    }

    class BleEventCallback {
        <<abstract>>
        +onAdapterChange(boolean)
        +onDiscoveryBleChange(boolean)
        +onDiscoveryBle(BluetoothDevice, BleScanInfo)
        +onBleConnection(BluetoothDevice, int)
        +onBleServiceDiscovery(BluetoothDevice, int, List~BluetoothGattService~)
        +onBleNotificationStatus(BluetoothDevice, UUID, UUID, int)
        +onBleDataBlockChanged(BluetoothDevice, int, int)
        +onBleDataNotification(BluetoothDevice, UUID, UUID, byte[])
        +onBleWriteStatus(BluetoothDevice, UUID, UUID, byte[], int)
        +onConnectionUpdated(BluetoothDevice, int, int, int, int)
        +onSwitchBleDevice(BluetoothDevice)
    }

    class BleEventCallbackManager {
        +onAdapterChange(boolean)
        +onBleConnection(BluetoothDevice, int)
        +onBleDataNotification(BluetoothDevice, UUID, UUID, byte[])
        +callbackEvent(Consumer~BleEventCallback~)
    }

    IBleEventCallback <|-- BleEventCallback
    BleEventCallback <-- BleEventCallbackManager : 遍历通知
  • IBleEventCallback:定义全部 11 个事件的完整契约,是回调的"接口规范"。
  • BleEventCallback:抽象类,为每个接口方法提供空实现,形成适配器模式(Adapter)。业务方继承它后只需覆写关心的方法,不必为不关心的事件写空方法,降低接入成本。
  • BleEventCallbackManager:继承杰理基础库的 BaseCallbackHelper<BleEventCallback>,内部维护注册回调集合,提供 addCallback / removeCallback 能力,并以 callbackEvent(...) 统一遍历分发。

事件分类与语义

BleEventCallbackManager 提供的 11 个事件可归为四类:

分类事件方法触发时机关键参数含义
系统状态onAdapterChange(boolean bEnabled)手机蓝牙开关状态变化bEnabled:蓝牙是否开启
扫描onDiscoveryBleChange(boolean bStart)BLE 扫描开始/停止bStart:是否开始扫描
扫描onDiscoveryBle(BluetoothDevice device, BleScanInfo bleScanMessage)扫描到设备bleScanMessage:扫描附加信息
连接onBleConnection(BluetoothDevice device, int status)连接状态变化status:BluetoothProfile.STATE_CONNECTED/DISCONNECTED
连接onBleServiceDiscovery(BluetoothDevice device, int status, List<BluetoothGattService> services)GATT 服务发现完成status:BluetoothGatt.GATT_SUCCESS 等
连接onConnectionUpdated(BluetoothDevice device, int interval, int latency, int timeout, int status)连接参数(interval/latency/timeout)更新对应 GATT connection priority 结果
连接onSwitchBleDevice(BluetoothDevice device)切换当前连接设备多设备场景下通知上层切换
数据通道onBleNotificationStatus(BluetoothDevice device, UUID serviceUuid, UUID characteristicUuid, int status)通知特征使能/去使能结果携带 service/characteristic UUID
数据通道onBleDataBlockChanged(BluetoothDevice device, int block, int status)数据块(block)状态变化OTA 大包分块发送时的块进度
数据通道onBleDataNotification(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data)收到设备主动通知(下行数据)data:设备回传的原始字节
数据通道onBleWriteStatus(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data, int status)写特征完成状态data:写入的字节,status:写入结果

分发机制:callbackEvent 统一出口

BleEventCallbackManager 的所有事件方法都遵循同一模式:将事件参数包装为 lambda,交给 callbackEvent 执行。例如:

public void onAdapterChange(boolean bEnabled) {
    callbackEvent(callback -> callback.onAdapterChange(bEnabled));
}

Source: BleEventCallbackManager.java

设计意图: callbackEvent 由 BaseCallbackHelper 实现,负责三件事:

  1. 遍历所有已注册的 BleEventCallback;
  2. 对每个回调执行 lambda 中的对应方法(即分发事件);
  3. 处理线程切换/异常隔离,避免单个回调异常影响其他监听者。

这种"管理器只做分发、不做业务"的设计,使 BleManager 在触发事件时只需一行调用(如 mCallbackManager.onBleConnection(device, status)),业务逻辑全部沉淀在回调实现侧,职责单一、易于测试。

BleEventCallback 空实现的作用

public abstract class BleEventCallback implements IBleEventCallback {

    @Override
    public void onAdapterChange(boolean bEnabled) {

    }

    @Override
    public void onBleConnection(BluetoothDevice device, int status) {

    }
    // ...其余方法同样为空实现
}

Source: BleEventCallback.java

设计意图: 接口 + 空实现抽象类的组合是 Android 回调的经典写法。接口约束契约(防止漏实现),抽象类提供"安全默认值"(防止业务方被迫实现无关方法)。OTA SDK 上层(如 UpgradeFragment)正是继承 BleEventCallback 并覆写 onBleConnection、onBleDataNotification 等关键事件来驱动升级流程。

BleManager 通道管理

单例与初始化

BleManager 采用双重检查锁(Double-Checked Locking)单例,确保整个进程只有一个 BLE 通道实例:

public static BleManager getInstance() {
    if (instance == null) {
        synchronized (BleManager.class) {
            if (instance == null) {
                instance = new BleManager(MainApplication.getInstance());
                JL_Log.w(TAG, "init", "instance : " + instance);
            }
        }
    }
    return instance;
}

Source: BleManager.java

构造函数(BleManager.java)完成四件事:

  1. 校验并缓存 Context,必要时同步给杰理基础库的 CommonUtil(全局主上下文);
  2. 获取 BluetoothAdapter;Android 5.0+(LOLLIPOP)获取 BluetoothLeScanner;
  3. 创建 ReConnectHelper(context, this)——断线重连辅助器,需要回调用 this(即 BleManager);
  4. 调用 registerReceiver() 注册系统广播接收器(如蓝牙开关变化)。

单例持有以下关键成员:

成员类型职责
mBleDeviceMapMap<String, BleDevice>按设备地址索引的连接状态容器
mDiscoveredBleDevicesList<BluetoothDevice>扫描发现设备缓存
mCallbackManagerBleEventCallbackManager事件分发出口
mHandlerHandler(Looper.getMainLooper())全部超时/延迟任务的驱动
isBleScanningvolatile boolean扫描状态标志(并发可见性)

核心流程:连接 → 发现服务 → 使能通知 → 数据收发

sequenceDiagram
    participant App as App / 上层
    participant BM as BleManager
    participant GATT as BluetoothGatt
    participant ECM as BleEventCallbackManager
    participant CB as BleEventCallback

    App->>BM: connectBleDevice(device)
    BM->>GATT: connectGatt(context, autoConnect, callback)
    GATT-->>BM: onConnectionStateChange(STATE_CONNECTED)
    BM->>ECM: onBleConnection(device, CONNECTED)
    ECM->>CB: 遍历回调 onBleConnection(...)
    BM->>GATT: discoverServices()
    GATT-->>BM: onServicesDiscovered(GATT_SUCCESS, services)
    BM->>ECM: onBleServiceDiscovery(device, status, services)
    ECM->>CB: 遍历回调 onBleServiceDiscovery(...)
    BM->>GATT: setCharacteristicNotification / 写 CCCD 描述符
    GATT-->>BM: onDescriptorWrite 或 onCharacteristicWrite
    BM->>ECM: onBleNotificationStatus(device, uuid, uuid, status)
    Note over BM,SBDT: 通道就绪,开始数据收发
    GATT-->>BM: onCharacteristicChanged(data)
    BM->>ECM: onBleDataNotification(device, uuid, uuid, data)
    ECM->>CB: 遍历回调 onBleDataNotification(...)
    App->>BM: sendData(device, data)
    BM->>SBDT: 入队 BleSendTask
    SBDT->>GATT: writeCharacteristic(...)
    GATT-->>BM: onCharacteristicWrite(status)
    BM->>ECM: onBleWriteStatus(device, uuid, uuid, data, status)

流程要点:

  • 状态机推进:每一步 GATT 操作(连接、发现服务、使能通知)完成后,BleManager 都通过 mCallbackManager 广播对应事件;上层依据事件驱动 OTA 状态机(如 MultiOTAState 系列)。
  • 数据下行靠通知:设备主动上报使用 onCharacteristicChanged → onBleDataNotification;数据上行靠写:应用写入使用 writeCharacteristic → onBleWriteStatus。两条路径在事件层语义分离,便于上层区分"设备应答"与"本机写入结果"。
  • 发送串行化:BleManager 将写入请求封装为 BleSendTask 交给 SendBleDataThread 队列,避免多个写并发导致 GATT 层错误;发送结果通过 OnWriteDataCallback 回传。

主线程 Handler 超时机制

BleManager 内部所有超时都用主线程 Handler 驱动(BleManager.java)。8 个消息码分别对应一个阶段的安全网:

消息码值触发动作
MSG_SCAN_BLE_TIMEOUT0x1010stopLeScan() 停止扫描(12s)
MSG_CONNECT_BLE_TIMEOUT0x1011disconnectBleDevice(device) 断开连接(40s)
MSG_SCAN_HID_DEVICE0x1012findHidDevice() 扫描 HID 设备
MSG_NOTIFY_BLE_TIMEOUT0x1013disconnectBleDevice(device) 通知使能超时断开
MSG_CHANGE_BLE_MTU_TIMEOUT0x1014回退 MTU 为 BluetoothConstant.BLE_MTU_MIN,按已连接处理
MSG_DISCOVER_SERVICES_TIMEOUT0x1015若已有服务则强制触发 onServicesDiscovered;否则未超重连上限则标记重连并断开
MSG_DISCONNECT_BLE_TIMEOUT0x1016closeGatt(gatt) 并回调 STATE_DISCONNECTED
MSG_CHECK_SYSTEM_BLE_TIMEOUT0x1017停止系统 BLE 状态检查线程

例如连接超时处理:

case MSG_CONNECT_BLE_TIMEOUT: {
    if (!(msg.obj instanceof BluetoothDevice)) return false;
    BluetoothDevice device = (BluetoothDevice) msg.obj;
    JL_Log.i(TAG, "MSG_CONNECT_BLE_TIMEOUT", "device : " + printDeviceInfo(device));
    disconnectBleDevice(device);
    break;
}

Source: BleManager.java

设计意图: Android BLE 的 GATT 回调在某些机型上可能"静默丢失"(系统不回调也不报错),单靠回调驱动流程会永久卡死。因此每个关键阶段都设置超时兜底:要么按成功路径补齐(如 MTU 超时回退最小值后继续)、要么清理资源并触发重连,保证通道状态机总能收敛。这也是 RECONNECT_BLE_DELAY = 2000ms 与 ReConnectHelper 存在的意义——失败后延迟重试而不是僵死。

通道常量配置

常量值说明
BLE_UUID_SERVICEBluetoothConstant.UUID_SERVICEBLE 服务 UUID(杰理协议固定值)
BLE_UUID_WRITEBluetoothConstant.UUID_WRITE写特征 UUID
BLE_UUID_NOTIFICATIONBluetoothConstant.UUID_NOTIFICATION通知特征 UUID
BLE_UUID_NOTIFICATION_DESCRIPTOR00002902-0000-1000-8000-00805F9B34FBCCCD 客户端特征配置描述符(标准 GATT)
SEND_DATA_MAX_TIMEOUT8000 ms单次写数据最大超时
SCAN_BLE_TIMEOUT12000 ms扫描超时
CONNECT_BLE_TIMEOUT40000 ms连接超时
CALLBACK_TIMEOUT6000 ms回调等待超时
RECONNECT_BLE_DELAY2000 ms断线重连延迟
MIN_CONNECT_TIME8000 ms最小连接保持时间

UUID 常量直接复用杰理基础库 BluetoothConstant(BleManager.java),确保与设备端固件协议严格一致;CCCD 描述符 UUID 0x2902 是 BLE 标准值,用于使能 notification。

使用示例

以下示例均从 SDK 源码中提取。

示例 1:注册事件回调并监听连接与数据

上层(如 UpgradeFragment)继承 BleEventCallback,只覆写关心的连接与数据事件,然后注册到通道:

public abstract class BleEventCallback implements IBleEventCallback {

    @Override
    public void onBleConnection(BluetoothDevice device, int status) {
        // 连接状态变化:status 为 STATE_CONNECTED / STATE_DISCONNECTED
    }

    @Override
    public void onBleDataNotification(BluetoothDevice device, UUID serviceUuid,
                                      UUID characteristicsUuid, byte[] data) {
        // 设备主动上报的数据(OTA 应答帧)
    }
    // 其余方法默认空实现,可选择性覆写
}

Source: BleEventCallback.java

示例 2:获取通道单例

BleManager manager = BleManager.getInstance();
// 之后可调用扫描、连接、发送等通道方法

Source: BleManager.java

示例 3:事件分发器的触发模式(通道内部)

BleManager 在底层 GATT 回调中调用分发器,完成事件转译:

public void onBleConnection(BluetoothDevice device, int status) {
    callbackEvent(callback -> callback.onBleConnection(device, status));
}

public void onBleDataNotification(BluetoothDevice device, UUID serviceUuid,
                                  UUID characteristicsUuid, byte[] data) {
    callbackEvent(callback -> callback.onBleDataNotification(device, serviceUuid, characteristicsUuid, data));
}

public void onBleWriteStatus(BluetoothDevice device, UUID serviceUuid,
                             UUID characteristicsUuid, byte[] data, int status) {
    callbackEvent(callback -> callback.onBleWriteStatus(device, serviceUuid, characteristicsUuid, data, status));
}

Source: BleEventCallbackManager.java

说明: 三个示例分别展示了"回调定义侧"、"通道入口侧"与"分发触发侧",覆盖事件回调的完整闭环。实际接入时,业务方只需做示例 1(继承 + 注册),通道内部机制无需改动。

API Reference

BleEventCallbackManager(事件分发器)

继承 BaseCallbackHelper<BleEventCallback>,全部方法为 void,无返回值、不抛受检异常。参数含义见"事件分类与语义"表。

方法签名说明
onAdapterChange(boolean bEnabled)系统蓝牙开关变化
onDiscoveryBleChange(boolean bStart)扫描开始/结束
onDiscoveryBle(BluetoothDevice device, BleScanInfo bleScanMessage)扫描到设备
onBleConnection(BluetoothDevice device, int status)连接状态变化
onBleServiceDiscovery(BluetoothDevice device, int status, List<BluetoothGattService> services)服务发现完成
onBleNotificationStatus(BluetoothDevice device, UUID serviceUuid, UUID characteristicUuid, int status)通知使能结果
onBleDataBlockChanged(BluetoothDevice device, int block, int status)数据块进度变化
onBleDataNotification(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data)收到设备通知数据
onBleWriteStatus(BluetoothDevice device, UUID serviceUuid, UUID characteristicsUuid, byte[] data, int status)写特征完成
onConnectionUpdated(BluetoothDevice device, int interval, int latency, int timeout, int status)连接参数更新
onSwitchBleDevice(BluetoothDevice device)切换当前设备

BleEventCallback(回调适配基类)

  • 抽象类,实现 IBleEventCallback 的全部 11 个方法为空实现。
  • 继承方式:class MyCallback extends BleEventCallback { ... }。
  • 设计意图:空实现使业务方与通道解耦——未覆写的事件自动忽略,覆写的事件通过 BleEventCallbackManager 在触发时被调用。

BleManager(通道管理器,部分方法)

方法说明
static BleManager getInstance()获取进程级单例(双重检查锁)
void registerCallback(BleEventCallback cb) / void unregisterCallback(...)注册/注销事件回调(由 BleEventCallbackManager 透出)
connectBleDevice(BluetoothDevice device)发起 GATT 连接(40s 超时兜底)
disconnectBleDevice(BluetoothDevice device)断开连接(带超时强制 closeGatt)
sendData(device, byte[] data, OnWriteDataCallback cb)封装 BleSendTask 入队串行发送(8s 超时)

说明:BleManager 共有 1200+ 行(BleManager.java),本页仅列出与"通道与事件回调"主题直接相关的入口。扫描(startLeScan/stopLeScan)、MTU 协商(changeMtu)、通知使能(notifyCharacteristic)等完整方法清单请直接查阅源码。

相关接口与模型

  • IBleOp:通道操作能力接口(连接、断开、发送等抽象)。
  • OnWriteDataCallback:写数据完成回调,供 SendBleDataThread 回传写结果。
  • OnThreadStateListener:发送线程状态监听。
  • BleDevice:连接设备状态机(GATT 引用、MTU、重连计数、isOverReconnectLimit())。
  • BleScanInfo:扫描附加信息(如广播数据解析结果)。
  • BleConnectParam:连接参数(扫描/连接/重连配置)。
  • BleSendTask:发送任务封装(设备、数据、回调)。

失败模式、边界情况与并发

失败模式与兜底策略

失败场景表现兜底策略
扫描无结果12s 内无设备MSG_SCAN_BLE_TIMEOUT 强制 stopLeScan(),避免资源泄漏
连接超时40s 未连上(GATT 回调静默丢失)MSG_CONNECT_BLE_TIMEOUT 调用 disconnectBleDevice 清理,触发 ReConnectHelper 重连
服务发现超时discoverServices 无回调若有已缓存服务则强制走 onServicesDiscovered(GATT_SUCCESS);否则未超重连上限则标记重连并断开
MTU 协商超时requestMtu 无回调回退 BLE_MTU_MIN 并按已连接继续,保证通道不因 MTU 失败而卡死
通知使能超时写 CCCD 无回调MSG_NOTIFY_BLE_TIMEOUT 断开设备
写数据超时单次写 8s 无结果SEND_DATA_MAX_TIMEOUT 由发送线程判定失败并回调 OnWriteDataCallback
系统蓝牙异常蓝牙被关闭/驱动异常onAdapterChange(false) 通知上层,CheckSystemBleThread + MSG_CHECK_SYSTEM_BLE_TIMEOUT 兜底

设计意图: 通道层把"系统回调不可靠"当作默认前提,每一阶段都布置超时安全网(安全网清单见"主线程 Handler 超时机制")。这显著提升了 OTA 长任务的健壮性——升级过程动辄数分钟,任何一步卡死都可能导致固件半写状态。

并发与线程模型

  • 超时与调度全部收敛在主线程 Handler:mHandler 绑定 Looper.getMainLooper(),消息按序执行,避免多线程操作 GATT 的竞态。
  • volatile 状态标志:instance、isBleScanning 等跨线程读写的字段用 volatile 保证可见性;单例初始化用 synchronized 双重检查。
  • 发送队列串行化:SendBleDataThread 是独立的发送线程,BleSendTask 按序消费,保证同一设备上 GATT 写操作不并发——这是 Android BLE 规范(单连接单写)的硬性要求。
  • 集合的线程安全注意:mBleDeviceMap(HashMap)与 mDiscoveredBleDevices(ArrayList)为普通集合,主要在 GATT 回调线程(Binder 线程池)与主线程间访问,实际使用中依赖"主线程 Handler 串行化"约束访问时机;扩展时若新增跨线程读写,需自行加锁。

边界情况

  • MTU 回退路径:MTU 协商失败不中断连接,回退 BLE_MTU_MIN 继续走已连接流程,保证低速但可用的通道。
  • 重连上限:BleDevice.isOverReconnectLimit() 决定服务发现失败后是否继续重连,防止无限重连消耗资源。
  • 多设备切换:onSwitchBleDevice 事件支持多设备场景下的通道切换通知,mBleDeviceMap 按地址索引管理多设备状态。

性能与运维注意事项

  • 扫描超时 12s 是"建议最小扫描时长"(源码注释),实际使用应结合 UI 交互控制扫描窗口,避免长时间扫描耗电。
  • 写数据 8s 超时 对 OTA 大包分块传输是硬约束;若单包写入频繁超时,应检查 MTU 与设备端应答节奏,而不是盲目提高超时。
  • 日志:BleManager 全程使用 JL_Log(TAG = BleManager),且 printDeviceInfo 打印设备关键信息,线上排查连接/超时问题可据此定位。
  • 主线程安全网消息通过 Handler.removeCallbacks 与 sendMessageDelayed 管理,需注意在断开连接后及时移除未触发的超时消息,避免"幽灵回调"。

扩展点

  1. 自定义业务回调:继承 BleEventCallback 并注册到 BleEventCallbackManager,即可在不动通道代码的前提下订阅任意事件组合(观察者模式的天然扩展性)。
  2. 发送结果回调:OnWriteDataCallback 允许上层感知每次写的成败,可用于实现自定义重传/流控策略。
  3. 重连策略:ReConnectHelper 为可替换的协作组件,重连延迟 RECONNECT_BLE_DELAY、重连上限等策略可通过其实现调整。
  4. 接口抽象:IBleOp / OnThreadStateListener 将操作与线程状态抽象为接口,便于单元测试替身(mock)与未来替换底层 BLE 实现(如迁移到 Jetpack Bluetooth)。

测试

  • 通道层依赖 Android 系统 BLE 栈,核心逻辑(单例、超时消息、事件分发)适合以 mock BluetoothGatt / BluetoothDevice 进行单元测试。
  • BleEventCallbackManager 的分发逻辑可完全脱离蓝牙硬件测试:注册若干回调后逐个触发 11 个事件方法,断言各回调被正确调用——这验证了"分发与业务解耦"的可测性设计。
  • 事件回调的"空实现抽象类"使测试子类只需覆写被测事件,大幅降低测试样板代码。

Related Links

  • BleEventCallbackManager.java — 事件分发器源码
  • BleManager.java — BLE 通道管理器源码
  • BleEventCallback.java — 回调适配基类
  • IBleEventCallback.java — 回调接口定义
  • interfaces/IBleOp.java、interfaces/OnWriteDataCallback.java、interfaces/OnThreadStateListener.java — 通道操作与发送回调接口
  • model/BleDevice.java、model/BleScanInfo.java、model/BleConnectParam.java、model/BleSendTask.java — 通道数据模型
  • SendBleDataThread.java — 串行发送线程
  • 相关页面:OTA 升级流程、文件监听(OtaFileObserver)、全局配置(ConfigHelper)
Prev
蓝牙扫描与连接管理
Next
OTA 升级流程与状态模型