【android bluetooth 框架分析 01】【关键线程 1】【关键线程介绍】

news2025/4/12 15:07:52

在这里插入图片描述

1. 为什么学习蓝牙协议栈之前,必须先梳理清楚这几大线程?

为什么 学习协议栈之前 最好是要先梳理清楚 关键线程

  • bt_stack_manager_thread
  • bt_jni_thread
  • bt_main_thread
  • bt_a2dp_sink_worker_thread

1.1 蓝牙协议栈是典型的“多线程异步系统”

蓝牙协议栈中各模块的初始化、通信、状态回调不是同步执行,而是分散在线程中通过消息队列 / 回调调度完成的。
所以:

🔍 你理解不了线程的职责、执行顺序,就等于你看不到协议栈的真实运行路径。


1.2 各线程的定位和使命

线程主要职责你必须理解的理由
bt_stack_manager_thread控制协议栈生命周期(init/startup/shutdown/cleanup)它是协议栈“主控台”,如果你不清楚它在干嘛,无法理解栈是怎么从无到有、有到无的
bt_jni_threadJNI 层 → native 层的事件调度、回调通知Java 层的蓝牙开关、回调都从这来,你必须知道怎么从 Java 控 native
bt_main_thread执行主线程模块任务(如 BTA/BTE 各模块调度)大量如 bta_sys_event()btm_ble_xxx() 都跑在这里,是“核心业务线程”
bt_a2dp_sink_worker_thread专门处理 A2DP sink 数据包的接收、解码如果你搞音频,必须清楚它什么时候开、怎么调度音频数据,避免阻塞或延迟音频

1.3 举个例子:打开蓝牙时线程配合流程

  1. Java 调用 adapter.enable()

  2. → 触发 JNI 调用 bt_interface_t.enable()

  3. → JNI Thread 把 enable 请求 postbt_stack_manager_thread

  4. bt_stack_manager_thread 调用 event_start_up_stack()

  5. → 多个模块在 bt_main_thread 中初始化(比如 BTA_dm_enable()

  6. → 初始化完成后,从 bt_jni_thread 回调 Java 层 onBluetoothEnabled()

你看,不懂线程,就根本看不出上面这些跳转背后的逻辑!


1.4 总结一句话

搞清楚这几个核心线程,就是搭建起你理解整个蓝牙协议栈“运作模型”的基础骨架。

之后不管你调试 A2DP 不通、BLE 扫描失败,还是 callback 没响应——
第一步就是看事件跑到哪个线程了、卡在谁那了。

2. 关键线程预览

本节先带大家粗略的看看各个线程 的用途, 稍后会有详细章节,一一介绍。

01-10 01:47:11.367588  2008  2539 I droid.bluetooth: [0110/014711.367540:INFO:message_loop_thread.cc(226)] Run: message loop starting for thread bt_stack_manager_thread


01-10 01:47:11.370394  2008  2542 I droid.bluetooth: [0110/014711.370351:INFO:message_loop_thread.cc(226)] Run: message loop starting for thread bt_jni_thread


01-10 01:47:12.932886  2008  3002 I bt_stack: [INFO:message_loop_thread.cc(226)] Run: message loop starting for thread bt_main_thread


01-10 01:47:13.152122  2008  3073 I bt_stack: [INFO:message_loop_thread.cc(226)] Run: message loop starting for thread bt_a2dp_sink_worker_thread
  • 蓝牙协议栈 启动时就会创建如下四个线程
    • bt_stack_manager_thread
    • bt_jni_thread
    • bt_main_thread
    • bt_a2dp_sink_worker_thread

2.1 bt_stack_manager_thread(协议栈管理线程)

作用

  • 负责蓝牙协议栈的全局管理,比如启动/关闭蓝牙、切换模式(BLE/经典蓝牙)

  • 协调各个模块的初始化(HCI、A2DP、AVRCP等)

  • 处理系统级事件(如蓝牙开关状态变化、设备连接/断开)

特点

  • 相当于蓝牙协议栈的"总指挥"

  • 所有关键操作都要经过它来调度


2.2 bt_jni_thread(JNI通信线程)

作用

  • 专门处理Java层和Native层之间的通信
  • 把Java应用的蓝牙请求(如连接设备、播放音乐)翻译成C++层的指令
  • 把Native层的事件(如连接状态变化)回调给Java层

特点

  • 相当于"翻译官"
  • 是Android蓝牙框架特有的线程

2.3 bt_main_thread(主线程)

作用

  • 负责蓝牙协议栈的核心消息循环
  • 处理来自各模块的异步事件和消息
  • 维护蓝牙协议栈的整体运行状态

特点

  • 相当于"中枢神经系统"
  • 不直接处理具体业务,主要负责消息分发

2.4 bt_a2dp_sink_worker_thread(A2DP接收线程)

作用

  • 专门处理蓝牙音频数据流(A2DP协议)
  • 负责音频数据的接收、解码和传输
  • 保证音频流的实时性和稳定性

特点

  • 相当于"专职音频处理员"
  • 对实时性要求极高

2.5 四个线程的关系

  1. 调用流程(自上而下)

    Java应用 → bt_jni_thread(翻译请求)
    → bt_stack_manager_thread(分配任务)
    → bt_main_thread(分发消息)
    → bt_a2dp_sink_thread(处理音频)

  2. 事件上报(自下而上)

    硬件事件 → bt_main_thread(接收)
    → bt_stack_manager_thread(处理)
    → bt_jni_thread(回调Java)
    → 通知应用

  3. 协作特点

    • bt_jni_thread是唯一直接与Java层交互的线程

    • bt_stack_manager_thread掌握最高控制权

    • bt_main_thread是消息中转站

    • bt_a2dp_sink_thread是专职工作者


2.6 关键设计思想

  1. 职责分离:每个线程只做特定工作,避免相互干扰
  2. 线程安全:通过消息队列实现跨线程通信
  3. 实时性保障:关键任务(如音频)有独立线程
  4. 层次清晰:Java层→管理层→核心层→硬件层逐级对接

这样设计既保证了蓝牙功能的可靠性,又确保了高性能和低延迟。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2331144.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CAS与sychronized优化

文章目录 CAS优化sychronized优化 CAS优化 CAS 优化过程: CAS是一种乐观锁机制,它通过比较内存中的值与预期值是否一致来决定是否更新。如果一致,则更新;如果不一致,则说明有其他线程修改了该值,CAS操作失败&#xff…

软考中级-软件设计师 2023年上半年下午题真题解析:通关秘籍+避坑指南

📚 目录(快速跳转) 大题(下午题)(每题15分,共75分)一、数据流图/数据库设计 💾🌾 试题一:农事管理服务平台数据流分析问题1:实体识别问…

数据结构|排序算法(二)插入排序 希尔排序 冒泡排序

一、插入排序 1.算法思想 插入排序(Insertion Sort)是一种简单的排序算法,其基本思想是:将待排序的元素插入到已经有序的序列中,从而逐步构建有序序列。 具体过程如下: 把待排序的数组分为已排序和未排…

案例-流量统计

1.建一个data目录,在data下建log.txt文件 输入手机号码 上行流量 下行流量 2.在com.example.flow下建四个Java类3.flowBean flowMapper flowReducer flowDriver

Codeforces Round 1011 (Div. 2)

Dashboard - Codeforces Round 1011 (Div. 2) - Codeforces Problem - B - Codeforces 题目大意: 给你一个数组,你可以用一段子序列中没有出现的最小非负整数,替换数组中的组序列,经过若干操作,让数组变为长度为1,值…

时序数据异常检测-综述

更新中 异常检测基本概念 广义的Out-of-Distribution(广义的OOD)来描述异常检测的相关问题。OOD包括五个相关的子领域,分别为Anomaly Detection(AD)、Novelty Detection(ND)、Open Set Recogntion(OSR)、Out-of-Distribution(OOD)和Outlier Detection(OD)。这5个…

多类型医疗自助终端智能化升级路径(代码版.下)

医疗人机交互层技术实施方案 一、多模态交互体系 1. 医疗语音识别引擎 # 基于Wav2Vec2的医疗ASR系统 from transformers import Wav2Vec2Processor, Wav2Vec2ForCTC import torchaudioclass MedicalASR:def __init__(self):self.processor = Wav2Vec2Processor.from_pretrai…

蓝桥杯专项复习——双指针

目录 双指针算法:双指针算法-CSDN博客 最长连续不重复子序列 P8783 [蓝桥杯 2022 省 B] 统计子矩阵 双指针优化思路:当存在重复枚举时,可以考虑是否能使用双指针进行优化 双指针算法:双指针算法-CSDN博客 最长连续不重复子序列…

BetaFlight参数配置解读

BetaFlight参数配置解读 📌相关篇《Betaflight固件编译和烧录说明》🥕各型号已编译好的配置文件资源(.config):https://github.com/betaflight/unified-targets/tree/master/configs/default🌿各型号配置头…

Java 容器源码分析

一、哈希表 1、引入 hash 表 在无序数组中按照内容查找,效率底下,时间复杂度是 O(n) 在有序数组中按照内容查找,可以使用折半查找,时间复杂度 O(log2n) 哈希表可以不进行比较,通过计算得到地…

【Java中级】11章、枚举 - java引用数据类型,枚举介绍、快速入门,了解枚举类的基本使用方式【1】

文章内容: 自定义实现枚举enum关键字实现枚举 ❤️内容涉及枚举的定义,快速入门,注意事项和小题巩固知识点 🌈 跟着B站一位老师学习的内部类内容,现写这篇文章为学习内部类的小伙伴提供思路支持,希望可以一…

Jmeter 插件【性能测试监控搭建】

1. 安装Plugins Manager 1.1 下载路径: Install :: JMeter-Plugins.org 1.2 放在lib/ext目录下 1.3 重启Jmeter,会在菜单-选项下多一个 Plugins Manager菜单,打开即可对插件进行安装、升级。 2. 客户端(Jmeter端) 2.1 安装plugins manager…

【ES系列】Elasticsearch从入门到精通保姆级教程 | 启篇

🔥 本系列将带你从零开始学习Elasticsearch,通过保姆级教程,手把手教你掌握这个强大的搜索与分析引擎。无论你是完全的新手,还是想系统学习ES的开发者,这个系列都能满足你的需求。 📚博主匠心之作,强推专栏: JAVA集合专栏 【夜话集】JVM知识专栏数据库sql理论与实战【…

Unity中Spine骨骼动画完全指南:从API详解到避坑实战

Unity中Spine骨骼动画完全指南:从API详解到避坑实战 一、为什么要选择Spine? Spine作为专业的2D骨骼动画工具,相比传统帧动画可节省90%资源量。在Unity中的典型应用场景包括: 角色换装系统(通过插槽替换部件)复杂连招系统(动画混合与过渡)动态表情系统(面部骨骼控制)…

C++Cherno 学习笔记day17 [66]-[70] 类型双关、联合体、虚析构函数、类型转换、条件与操作断点

b站Cherno的课[66]-[70] 一、C的类型双关二、C的union(联合体、共用体)三、C的虚析构函数四、C的类型转换五、条件与操作断点——VisualStudio小技巧 一、C的类型双关 作用:在C中绕过类型系统 C是强类型语言 有一个类型系统,不…

wordpress 利用 All-in-One WP Migration全站转移

导出导入站点 在插件中查询 All-in-One WP Migration备份并导出全站数据 导入 注意事项: 1.导入部分限制50MB 宝塔解决方案,其他类似,修改php.ini配置文件即可 2. 全站转移需要修改域名 3. 大文件版本,大于1G的可以参考我的…

【工具使用】在OpenBMC中使用GDB工具来定位coredump原因

在OpenBMC调试中,有时会产生coredump却不知道从哪里入手分析,GDB工具就可以提供帮助。 1 编译带GDB工具的镜像 OpenBMC镜像中默认没有加入GDB工具,因此首先需要编译一个带GDB工具的OpenBMC镜像用于调试。在recipes-phosphor/packagegroups/…

Linux系统(Ubuntu和树莓派)的远程操作练习

文章目录 一、实验一(一)实验准备(二)Ubuntu 下的远程操作(三)树莓派下的远程操作(四)思考 二、实验二1.talk程序2. C 编写 Linux 进程间通信(IPC)聊天程序 一…

高效创建工作流,可实现类似unreal engine的蓝图效果,内部使用多线程高效执行节点函数

文章目录 前言(Introduction)开发环境搭建(Development environment setup)运行(Run test)开发者(Developer)编译(Compile)报错 前言(Introductio…

Design Compiler:语法检查工具dcprocheck

相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 dcprocheck是一个在Design Compiler存在于安装目录下的程序(其实它是一个指向snps_shell的符号链接,但snps_shell可以根据启动命令名判…