【android bluetooth 框架分析 01】【关键线程 6】【主线程与核心子线程协作机制】
主线程与核心子线程的协作机制
一、蓝牙进程中的线程架构全景图
在Android蓝牙协议栈中,线程分工非常明确,形成了一个高效的协作体系。我们可以将其想象成一个医院的组织架构:
-
主线程:相当于医院的"前台接待处",负责与外界沟通和简单任务分发
-
bt_main_thread:相当于医院的"急诊中心",处理所有紧急和核心业务
-
bt_jni_thread:相当于医院的"翻译部门",负责Java与C++世界的沟通
-
bt_stack_manager_thread:相当于医院的"行政管理部门",负责整体协调
二、真正的主线程(进程主线程)的职责
1. 主要工作内容
主线程就像医院的接待大厅,主要负责:
-
应用生命周期管理:处理进程的启动、初始化、退出等
-
系统事件响应:处理来自Android系统的广播和回调
-
简单UI更新:如果有UI元素需要更新(如蓝牙开关状态)
-
线程创建与管理:负责创建和启动其他核心子线程
2. 典型工作场景举例
当用户点击"开启蓝牙"时:
-
主线程接收来自Settings应用的Binder调用
-
主线程简单验证参数后,将任务转发给bt_stack_manager_thread
-
主线程立即返回,避免阻塞UI
三、主线程与核心子线程的交互机制
1. 与bt_main_thread的交互
交互方式:通过do_in_main_thread
系列函数
数据流向:
-
下行数据(应用→控制器):
-
主线程接收JNI调用
-
通过
post_on_bt_main
将任务提交到bt_main_thread -
bt_main_thread处理HCI命令组装并发送
-
-
上行数据(控制器→应用):
-
bt_main_thread收到HCI事件
-
通过JNI回调接口通知主线程
-
主线程通过Binder通知应用
-
案例:处理蓝牙扫描结果
-
控制器发现设备后发送HCI事件
-
bt_main_thread的
btu_hci_msg_process
处理该事件 -
通过主线程的JNI接口回调到Java层
-
主线程通过BluetoothAdapter将结果广播给所有注册的应用
2. 与bt_jni_thread的交互
交互方式:通过JNIEnv和消息队列
特殊设计:
-
JNI调用有线程亲和性,必须固定线程处理
-
bt_jni_thread专门负责"翻译"工作
数据流向:
-
Java→Native:
-
Java层通过Binder调用到主线程
-
主线程将任务转发到bt_jni_thread
-
bt_jni_thread处理JNI转换后交给bt_main_thread
-
-
Native→Java:
-
bt_main_thread产生回调事件
-
通过bt_jni_thread的JNI环境调用Java方法
-
bt_jni_thread确保线程安全地执行回调
-
案例:处理配对请求
-
Java层BluetoothService收到配对请求
-
主线程通过JNI调用到bt_jni_thread
-
bt_jni_thread转换为native格式后提交给bt_main_thread
-
bt_main_thread处理配对流程
-
配对结果通过反向路径返回到Java层
3. 与bt_stack_manager_thread的交互
交互方式:通过异步消息和回调
管理范围:
-
蓝牙模块的启停控制
-
Profile服务的状态管理
-
系统配置变更处理
数据流向:
-
控制指令:
-
主线程收到系统指令(如关闭蓝牙)
-
通过异步消息通知bt_stack_manager_thread
-
管理线程协调各模块关闭
-
-
状态反馈:
-
管理线程完成操作后
-
通过主线程注册的回调函数通知结果
-
主线程更新系统状态
-
案例:处理蓝牙关闭流程
-
用户点击关闭蓝牙
-
主线程收到请求后立即返回
-
向bt_stack_manager_thread发送关闭指令
-
管理线程依次关闭各Profile
-
通知bt_main_thread停止协议栈
-
通过主线程回调通知Java层关闭完成
四、线程间的功能划分与数据流
1. 上行数据处理流程(设备→应用)
[蓝牙控制器]
↓ (HCI事件)
[bt_main_thread] 处理原始数据、协议解析
↓ (内部消息)
[bt_stack_manager_thread] 更新全局状态
↓ (JNI回调)
[bt_jni_thread] 数据格式转换
↓ (Binder/IPC)
[主线程] 系统广播分发
↓
[应用进程]
实例:蓝牙耳机连接音频流
-
控制器发送ACL数据包
-
bt_main_thread的acl_rcv_acl_data处理
-
通过L2CAP通道传递到A2DP模块
-
bt_jni_thread将音频数据转为Java对象
-
主线程传递给AudioService
2. 下行数据处理流程(应用→设备)
[应用进程]
↓ (Binder调用)
[主线程] 接收请求
↓ (任务分发)
[bt_stack_manager_thread] 验证请求有效性
↓ (内部消息)
[bt_main_thread] 生成HCI命令
↓ (HCI传输)
[蓝牙控制器]
实例:发送文件 via OBEX
-
应用调用BluetoothOppManager
-
主线程通过JNI到bt_jni_thread
-
bt_stack_manager_thread验证传输权限
-
bt_main_thread分片数据并通过RFCOMM发送
-
控制器通过无线电发送数据
五、为什么这样设计?优势分析
-
责任分离:
-
主线程:负责与系统交互
-
bt_main_thread:专注协议处理
-
bt_jni_thread:解决JNI线程亲和性问题
-
bt_stack_manager_thread:统一管理复杂状态
-
-
性能优化:
-
主线程不处理耗时操作,保证UI响应
-
bt_main_thread启用实时调度,确保协议时序
-
JNI操作集中处理,避免线程安全问题
-
-
错误隔离:
-
某个线程崩溃不会直接影响其他线程
-
协议栈核心(bt_main_thread)受到保护
-
-
扩展性:
-
新增Profile只需在bt_main_thread添加处理逻辑
-
系统接口变更只需调整主线程部分
-
六、典型案例分析
案例1:蓝牙设备连接全过程
-
扫描阶段:
-
主线程接收startDiscovery()调用
-
bt_stack_manager_thread协调扫描资源
-
bt_main_thread处理实际的HCI扫描命令
-
扫描结果通过反向路径回调到应用
-
-
配对阶段:
-
主线程接收createBond()调用
-
bt_jni_thread转换参数
-
bt_main_thread处理SSP配对流程
-
配对结果通过bt_jni_thread回调
-
-
连接阶段:
-
bt_main_thread建立ACL链路
-
bt_stack_manager_thread启动相关Profile
-
连接状态通过主线程广播
-
案例2:A2DP音频流传输
-
上行流(播放音乐):
-
手机接收音频数据包
-
bt_main_thread处理ACL数据
-
L2CAP重组数据帧
-
bt_jni_thread转换音频数据
-
主线程传递给AudioFlinger
-
-
下行控制(暂停/播放):
-
应用发送控制指令
-
主线程通过JNI传递
-
bt_main_thread生成AVRCP命令
-
控制器发送给耳机设备
-
七、异常处理机制
-
线程挂死检测:
-
主线程监控其他线程的心跳
-
超时后重启蓝牙协议栈
-
-
消息积压处理:
-
bt_main_thread监控消息队列深度
-
超过阈值时丢弃低优先级消息
-
-
错误恢复流程:
这种精细的线程划分和协作机制,使得Android蓝牙协议栈能够同时满足实时性、可靠性和扩展性的要求,为各种蓝牙功能提供了坚实的基础架构支持。
相关文章:
【android bluetooth 框架分析 01】【关键线程 6】【主线程与核心子线程协作机制】
主线程与核心子线程的协作机制 一、蓝牙进程中的线程架构全景图 在Android蓝牙协议栈中,线程分工非常明确,形成了一个高效的协作体系。我们可以将其想象成一个医院的组织架构: 主线程:相当于医院的"前台接待处"&#…...
蓝桥杯比赛 python程序设计——神奇闹钟
问题描述 小蓝发现了一个神奇的闹钟,从纪元时间(19701970 年 11 月 11 日 00:00:0000:00:00)开始,每经过 xx 分钟,这个闹钟便会触发一次闹铃 (纪元时间也会响铃)。这引起…...
旋转位置编码
旋转位置编码(Rotary Position Embedding,RoPE): 一种能够将相对位置信息依赖集成到 self-attention 中并提升 transformer 架构性能的位置编码方式。 和相对位置编码相比,RoPE 具有更好的外推性,目前是大模型相对位…...
2025年第十八届“认证杯”数学中国数学建模网络挑战赛【B题】完整版+代码+结果
2025年第十八届“认证杯”数学中国数学建模网络挑战赛B题完整word论文代码结果https://download.csdn.net/download/qq_52590045/90592749↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓…...
管理、切换多个 hosts工具之SwitchHosts
管理、切换多个 hosts工具之SwitchHosts 官网:https://switchhosts.vercel.app/zh github: https://github.com/oldj/SwitchHosts 原作者博客:https://oldj.net/article/2015/12/20/switchhosts-v3/ SwitchHosts是一个用于管理hosts文件的应用程序&…...
【Reinforcement Learning For Quadruped Control】2
奖励函数。奖励函数是状态和动作的函数 r t ( s t , a t , s t 1 ) r_t(s_t, a_t, s_{t1}) rt(st,at,st1),是强化学习(RL)算法的驱动力。在四足机器人等复杂系统的背景下,奖励可能是速度偏差与期望速度的差异、关节扭矩值…...
Windows启动总是卡在LOGO画面有哪些原因
1. 硬件问题 硬盘故障(HDD/SSD):坏道、损坏或接口松动。 内存故障:内存条接触不良或损坏。 外设冲突:U盘、移动硬盘、打印机等外接设备导致系统无法正常启动。 2. 系统文件损坏 Windows 关键文件丢失或损坏&#x…...
4月11日随笔
本来以为大风会很厉害,本来今天早八的微积分不想去了。但是起床发现并没有很大的风,还是去了。 中午回来的路上突然变天,雷阵雨转冰雹。下了大概半小时,所幸挨淋的不是很严重。 中午打了首胜,AI的基本弄完了…...
蓝桥杯 — — 接龙数列
蓝桥杯 — — 接龙数列 接龙数列 题源:0接龙数列 - 蓝桥云课 题目: 输入样例: 5 11 121 22 12 2023输出样例: 1分析: 首先观察评测用例规模, N N N 最大为 1 0 5 10^5 105,因此时间复杂度应…...
链式多分支规则树模型的应用
目录 引入 开始调用 初始化 执行流程 欢迎关注我的博客!26届java选手,一起加油💘💦👨🎓😄😂 引入 最近在学习一个项目中的链式多分枝规则树模型的使用,模型如下&#…...
【后端开发】初识Spring IoC与SpringDI、图书管理系统
文章目录 图书管理系统用户登录需求分析接口定义前端页面代码服务器代码 图书列表展示需求分析接口定义前端页面部分代码服务器代码Controller层service层Dao层modle层 Spring IoC定义传统程序开发解决方案IoC优势 Spring DIIoC &DI使用主要注解 Spring IoC详解bean的存储五…...
VMware虚拟机Ubuntu磁盘扩容
VMware中操作: 选择要扩容的虚拟机,点击编辑虚拟机设置 打开后点击磁盘——>点击扩展(注意:如果想要扩容的话需要删除快照) 调整到你想要的容量 点击上图的扩展——>确定 然后我们进到虚拟机里面 首先&#…...
嵌入式MCU常用模块
日后填坑。 无线通信模块 NRF24L01 基本介绍 使用方法 示例代码 蓝牙模块 基本介绍 使用方法 示例代码 WIFI模块 基本介绍 使用方法 示例代码 红外遥控模块 基本介绍 使用方法 示例代码 有线通信模块 can模块 基本介绍 使用方法 示例代码 传感器模块 DHT11模块 基本介绍 使用方…...
算法 模版
cin cout加快读取速度: ios::sync_with_stdio(false); 高精度*高精度 vector<int> mul(vector<int>& a, vector<int>& b) {vector<int>c(b.size()a.size()5,0);for (int i 0; i < a.size(); i) {for (int j 0; j < b.si…...
C++指针(三)
个人主页:PingdiGuo_guo 收录专栏:C干货专栏 文章目录 前言 1.字符指针 1.1字符指针的概念 1.2字符指针的用处 1.3字符指针的操作 1.3.1定义 1.3.2初始化 1.4字符指针使用注意事项 2.数组参数,指针参数 2.1数组参数 2.1.1数组参数的概念 2.1…...
二分查找4:35. 搜索插入位置
链接:35. 搜索插入位置 - 力扣(LeetCode) 题解: 本题是最基础的二分查找算法 class Solution { public:int searchInsert(vector<int>& nums, int target) {int left0;int rightnums.size()-1;int midleft(right-lef…...
数据可视化 —— 多边图应用(大全)
一、介绍: 多边形图,也就是在数据可视化中使用多边形来呈现数据的图表,在多个领域都有广泛的应用场景,以下为你详细介绍: 金融领域 投资组合分析:在投资组合管理中,多边形图可用于展示不同资…...
服务器加空间失败 growpart /dev/vda 1
[rootecm-2c5 ~]# growpart /dev/vda 1 unexpected output in sfdisk --version [sfdisk,来自 util-linux 2.23.2] [rootecm-2c5 ~]# xfs_info /dev/vda1 meta-data/dev/vda1 isize512 agcount21, agsize1310656 blks sectsz512 attr2, projid32bit1 crc1 finobt0…...
tree-sitter的grammar.js解惑
❓问题1:grammar.js 不是用正则表达式 /.../ 吗?为什么有 print 这样的字符串? ✅ 回答: grammar.js 分成两类“终结符”表示法: 表达方式含义xxx直接匹配该字符串字面量/regex/匹配符合正则的文本 💡 …...
前端-Vue3
1. Vue3简介 2020年9月18日,Vue.js发布版3.0版本,代号:One Piece(n 经历了:4800次提交、40个RFC、600次PR、300贡献者 官方发版地址:Release v3.0.0 One Piece vuejs/core 截止2023年10月,最…...
【毕设通关】——文献查阅
目录 🕒 1. 常见文献库🕒 2. 快速寻找文献🕒 3. 引用网页资料 🕒 1. 常见文献库 中文文献: CNKI中国知网万方数据维普资讯超星期刊 英文文献: 谷歌学术Sci-hubOALib(Open Access Library&am…...
贪心算法-跳跃游戏
55.跳跃游戏 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。输入…...
程序化广告行业(75/89):行业发展与PC端和移动端投放差异
程序化广告行业(75/89):行业发展与PC端和移动端投放差异 在互联网广告领域,程序化广告正发挥着越来越重要的作用。今天,咱们就来一起深入了解一下程序化广告行业,希望能和大家一起学习进步,共同…...
Windows 下搭建 Git 本地服务器并进行开发
目录 1. 安装 Git for Windows 2. 创建本地 Git 仓库(裸仓库) 3. 设置本地开发环境 (1) 在开发机器上克隆仓库 (2) 提交代码 4. 远程访问本地 Git 服务器 方法 1:使用 SSH 访问 (1) 配置 SSH 服务器 (2) 客户端连接 方法 2…...
C++中stack函数的用法示例
C++中stack函数的用法示例 std::stack 是C++标准模板库(STL)中的一个容器适配器,它提供了后进先出(LIFO)的数据结构。以下是stack的一些常用函数及其用法示例: 1. 基本操作 #include <iostream> #include <stack>int main() {// 创建一个整数栈std::stack<…...
网络安全1
一、网络安全的定义与重要性 定义 网络安全(信息技术安全):保护计算机系统和网络免受电子攻击的技术和过程,包括保护个人信息和企业数据不被盗窃、破坏或非法访问。涵盖范围:网络设备、数据传输、系统运行安全。 重要…...
腾讯会议for flatpak
今天想切换opensuse,无意间查询了腾讯会议等软件的下载方式,发现腾讯会议是deb包安装的。但是过程中,我发现flatpak仓库中居然有腾讯会议,然后尝试着在wayland下的debian12中进行了安装。 发现居然可以正常开启视频等操作。 下载…...
【C++初学】C++核心编程技术详解(二):类与继承
函数提高 3.1 函数默认参数 函数的形参可以有默认值,调用时可以省略这些参数。 示例代码: int func(int a, int b 10, int c 10) {return a b c; }int main() {cout << "ret " << func(20, 20) << endl;cout <<…...
紧急任务插入,如何不影响原计划
面对紧急任务插入,为确保不影响原计划,需要做到:重新明确任务优先级、合理调整资源配置、灵活管理时间和任务、建立紧急任务处理流程、有效沟通与反馈。其中,重新明确任务优先级最为关键。这可以帮助项目团队快速确定哪些任务需立…...
蓝桥杯赛前题
开始每个人能量为3 答题了,答题者1 扣分最后算 #include<bits/stdc.h> using namespace std;const int N1e510; int a[N]; int main(){int n,k,q;cin>>n>>k>>q;for(int i1;i<n;i){a[i]k; }for(int i1;i<q;i){int x;cin>>x;a[…...
ETL的核心概念与价值
在数字化转型的浪潮中,数据已成为企业决策的基石。然而,面对分散、异构且质量参差不齐的数据源,如何高效整合并挖掘其价值?这一问题的答案,指向了一项关键的技术——ETL(Extract-Transform-Load)…...
神经动力学系统与计算及AI拓展
大脑,一个蕴藏在我们颅骨之内的宇宙,以活动脉动,如同由电信号和化学信号编织而成的交响乐,精巧地协调着思想、情感和行为。但是,这种复杂的神经元舞蹈是如何产生我们丰富多彩的精神生活的呢?这正是神经动力…...
力扣DAY46-50 | 热100 | 二叉树:展开为链表、pre+inorder构建、路径总和、最近公共祖先、最大路径和
前言 中等 、困难 √,越来越有手感了,二叉树done! 二叉树展开为链表 我的题解 前序遍历树,当遇到左子树为空时,栈里pop节点,取右子树接到左子树位置,同时断开该右子树与父节点的连接&#x…...
备赛蓝桥杯-Python-考前突击
额,,离蓝桥杯开赛还有十个小时,最近因为考研复习节奏的问题,把蓝桥杯的优先级后置了,突然才想起来还有一个蓝桥杯呢。。 到目前为止python基本语法熟练了,再补充一些常用函数供明天考前再背背,算…...
蓝桥杯 Web 方向入门指南:从基础到实战
一、蓝桥杯 Web 方向简介 蓝桥杯是国内最具影响力的编程竞赛之一,Web 方向主要考察前端开发和后端服务能力。比赛形式为 4 小时限时编程,题型包括页面布局、数据交互、API 开发等。根据最新大纲,大学组需掌握 HTML5、CSS3、JavaScript、Vue.…...
生命篇---心肺复苏、AED除颤仪使用、海姆立克急救法、常见情况急救简介
生命篇—心肺复苏、AED除颤仪使用、海姆立克急救法、常见情况急救简介 文章目录 生命篇---心肺复苏、AED除颤仪使用、海姆立克急救法、常见情况急救简介一、前言二、急救1、心肺复苏(CPR)(1)适用情况(2)操作…...
C++Cherno 学习笔记day19 [76]-[80] std::optional、variant、any
b站Cherno的课[76]-[80] 一、如何处理OPTIONAL数据 std::optional二、单一变量存放多类型的数据 std::variant三、如何存储任意类型的数据 std::any四、如何让C运行得更快五、如何让C字符串更快 一、如何处理OPTIONAL数据 std::optional std::optional C17 数据是否存在是可选…...
【Python Requests 库详解】
目录 简介一、安装与导入安装导入 二、发送 HTTP 请求1. GET 请求基本请求URL 参数 2. POST 请求表单数据提交JSON 数据提交文件上传 3. 其他方法PUT 请求示例DELETE 请求示例 三、处理响应1. 响应内容解析文本内容处理二进制内容处理JSON 数据处理 2. 响应状态与头信息状态码检…...
二维偏序-蓝桥20102,没写完
代码: 暴力:只过了35%,双重for循环o(n^2)1e10; #include <iostream> #include <bits/stdc.h> using namespace std; const int N1e910; typedef long long LL; typedef pair<int,int> PII;int main() {// 请在此输入您的代码//相当于…...
ASEG的鉴定
等位基因特异性表达(Allele-Specific Expression, ASE)基因的鉴定是研究杂种优势和基因表达调控的重要手段。以下是鉴定ASE基因的详细流程和方法: ### **1. 实验设计与样本准备** - **选择材料**:选择杂交种及其亲本作为研究材料。例如,玉米中的B73和Mo17及其杂交组合B73…...
从零开始:在 GrapesJS Style Manager 中新增 row-gap 和 column-gap
在前端开发中,页面样式的灵活性和可扩展性至关重要。GrapesJS 作为一个强大的网页构建工具,其内置的 Style Manager 提供了常见的 CSS 样式的可视化设置,极大地方便了开发者和设计师。然而,随着项目需求的不断变化,有些…...
解决双系统ubuntu24.04开机出现花屏等情况
1. 问题描述: 刚刚装上的双系统ubuntu24.04开机就出现花屏情况 2. 解决方案 安装显卡驱动 查看显卡型号 查看显卡硬件支持的驱动类型 ubuntu-drivers devices如果输入没有反映,请更新软件源,或者换官方软件源 sudo add-apt-repository…...
基于SpringBoot的智慧社区管理系统(源码+数据库)
499基于SpringBoot的智慧社区管理系统,系统包含三种角色:管理员、用户主要功能如下。 【用户功能】 1. 首页:查看系统。 2. 超市商品:浏览超市中各类商品信息。 3. 动物信息:了解社区内的动物种类和相关信息。 4. 车位…...
通俗理解CLIP模型如何实现图搜图乃至文搜图
一、图搜图与文搜图 图搜图和文搜图的场景相信大家并不少见,比如度娘的搜索框就可以直接上传图片找到相似的图片,还有某宝某团都有这种上传图片匹配到相似商品或者商品页的推荐的功能。那比如我想搜一张“正在跳舞的狗”的图片,是不是就能搜…...
谷歌最近放出大招——推出全新“Agent Development Kit(简称ADK)
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
std::string` 类
以下是对 std::string 类中 修改操作 和 字符串操作 的示例代码,帮助你更好地理解这些函数的使用: 5. 修改操作 (1) operator 用于追加字符串、C 风格字符串或字符。 #include <iostream> #include <string>int main() {std::string str …...
Sping Cloud配置和注册中心
1.Nacos实现原理了解吗? Nacos是注册中心,主要是帮助我们管理服务列表。Nacos的实现原理大概可以从下面三个方面来讲: 服务注册与发现:当一个服务实例启动时,它会向Nacos Server发送注册请求,将自己的信息…...
Java基础 - 泛型(常见用法)
文章目录 泛型类泛型方法泛型类派生子类示例 1:子类固定父类泛型类型(StringBox 继承自 Box<String>)示例 2:子类保留父类泛型类型(AdvancedBox<T> 继承自 Box<T>)示例 3:添加子类自己的…...
待排序元素规模较小时,宜选取哪种排序算法效率最高
当待排序元素规模较小时,通常选择以下几种简单高效的排序算法,因为它们在小规模数据下具有更低的常数开销和良好的局部性表现: ✅ 插入排序(Insertion Sort) 推荐理由:在数据量小、数据部分有序的情况下&a…...
SAQ评级是什么,SAQ评级的意义?对企业发展好处
SAQ评级(Supplier Audit Questionnaire,供应商审计问卷评级)是供应链管理中常见的一种评估机制,主要用于对供应商的质量、合规性、风险管理能力等进行标准化审核和分级。它常见于汽车、电子、医药等对供应链要求严格的行业&#x…...