安卓触摸事件分发机制分析
1. 前言
🎯 一句话总结:
触摸事件(TouchEvent)会从 Activity
层开始,按从外到内的方式传递给每一个 ViewGroup/View,直到某个 View 消费(consume) 它,事件传递就会停止。
📌 事件分发三个关键方法
方法名 | 所在类 | 作用说明 |
---|---|---|
dispatchTouchEvent() | 所有 View/ViewGroup | 事件分发入口,决定是否继续向下传递 |
onInterceptTouchEvent() | 仅 ViewGroup | 是否拦截事件,阻止传递给子 View |
onTouchEvent() | 所有 View/ViewGroup | 事件的最终处理者(消费者) |
DecorView
是一个应用窗口的根容器,它本质上是一个FrameLayout
。DecorView
有唯一一个子View,它是一个垂直LinearLayout
,包含两个子元素,一个是TitleView
(ActionBar的容器),另一个是ContentView
(窗口内容的容器)。
Activity.dispatchTouchEvent()↓Window.superDispatchTouchEvent()↓DecorView.dispatchTouchEvent()↓ViewGroup.dispatchTouchEvent()↓- onInterceptTouchEvent() → 是否拦截?↓ ↓拦截自己处理 不拦截继续往下↓子View.dispatchTouchEvent()↓View.dispatchTouchEvent()↓- onTouchListener.onTouch()- onTouchEvent()
Activity.dispatchTouchEvent()
- 触摸事件从系统层传入,Activity 先接收。
- 通常会把事件传给当前的
DecorView
(根 View)。
ViewGroup.dispatchTouchEvent()
- 尝试调用
onInterceptTouchEvent()
判断是否拦截事件。- 返回 true:表示当前 ViewGroup 要处理,子 View 不再收到事件。
- 返回 false:继续把事件传给子 View。
- 尝试调用
- 子
View.dispatchTouchEvent()
如果是 ViewGroup,会重复上面的流程(递归)。- 如果是普通 View,直接调用
onTouchEvent()
。
- 如果是普通 View,直接调用
onTouchEvent()
- 如果返回
true
,表示事件被消费(消费后不会再向上传递)。 - 如果返回
false
,当前控件不处理,事件会被传回上层 ViewGroup 的onTouchEvent()
。
- 如果返回
2. Activity、ViewGroup、View事件分发机制分析
Activity事件分发机制
Activity.dispatchTouchEvent(MotionEvent event)
源码(Activity.java
仅关键代码):
public boolean dispatchTouchEvent(MotionEvent ev) {if (ev.getAction() == MotionEvent.ACTION_DOWN) {onUserInteraction();}if (getWindow().superDispatchTouchEvent(ev)) {return true;}return onTouchEvent(ev);
}
onUserInteraction()
:通知用户交互,和事件分发无关。- 调用
getWindow().superDispatchTouchEvent(ev)
:Window
是PhoneWindow
。PhoneWindow
把事件交给了DecorView
(一个 ViewGroup)处理。
- 如果
superDispatchTouchEvent(ev)
返回true
,说明事件被下面消费了。 - 否则调用
Activity.onTouchEvent(ev)
(比如点击空白处)。
ViewGroup 事件分发机制
DecorView
是 ViewGroup
,所以它遵循 ViewGroup 的事件分发规则。
ViewGroup.dispatchTouchEvent(MotionEvent ev)
源码(ViewGroup.java
仅关键代码):
ViewGroup.dispatchTouchEvent
代码可大致简化为下面这个样子
public boolean dispatchTouchEvent(MotionEvent ev) {// 1. 是否拦截事件boolean intercepted = onInterceptTouchEvent(ev);// 2. 如果没有拦截,遍历子 View 分发if (!intercepted) {for (int i = childrenCount - 1; i >= 0; i--) {final View child = children[i];if (child.dispatchTouchEvent(ev)) {return true;}}}// 3. 子 View 没有消费,自己处理return super.dispatchTouchEvent(ev);
}
详细代码可以查看ViewGroup.dispatchTouchEvent
中 dispatchTransformedTouchEvent
方法
private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,View child, int desiredPointerIdBits) {final boolean handled;// Canceling motions is a special case. We don't need to perform any transformations// or filtering. The important part is the action, not the contents.final int oldAction = event.getAction();if (cancel || oldAction == MotionEvent.ACTION_CANCEL) {event.setAction(MotionEvent.ACTION_CANCEL);if (child == null) {handled = super.dispatchTouchEvent(event);} else {handled = child.dispatchTouchEvent(event);}event.setAction(oldAction);return handled;}// 省略....return handled;}
onInterceptTouchEvent(ev)
:决定是否拦截事件(默认返回false
)。- 如果返回
true
,自己处理,不再传递给子 View。 - 如果没有拦截,会遍历子 View,调用子 View 的
dispatchTouchEvent(ev)
。 - 如果有任何一个子 View 返回了
true
,说明消费了事件,整个流程结束。 - 如果子 View 都没有消费,最后调用自己的
super.dispatchTouchEvent(ev)
,即作为普通 View 处理。
View 事件分发机制
View
是最终事件的接收者。
View.dispatchTouchEvent(MotionEvent ev)
源码(View.java
仅关键代码):
public boolean dispatchTouchEvent(MotionEvent event) {boolean result = false;// 1. 先判断是否需要触发 OnTouchListenerListenerInfo li = mListenerInfo;if (li != null && li.mOnTouchListener != null&& (mViewFlags & ENABLED_MASK) == ENABLED&& li.mOnTouchListener.onTouch(this, event)) {result = true;}// 2. 如果 OnTouchListener 没消费,再走 onTouchEventif (!result && onTouchEvent(event)) {result = true;}return result;
}
- 优先执行
onTouchListener.onTouch()
。- 如果返回
true
,表示事件被消费,不继续往下传递。
- 如果返回
- 否则走
onTouchEvent(event)
。
因为点击事件是在 onTouchEvent
中的 case MotionEvent.ACTION_UP:
中判断调用的,具体查看 View.performClickInternal()
方法。
这里就是,如果你设置了某个 View
的 OnTouchListener
并且在 onTouch
方法中返回 true
,那么这个 View
的 onClick
方法不会执行的原因。
3. 理解 ViewGroup 的递归式事件分发?
核心理解:递归式分发
- 父 ViewGroup 收到事件,先问自己:“要不要拦截?”(
onInterceptTouchEvent
)** - 如果 不拦截,就 找出被点击的子 View
- 然后 把事件递给子 View 的
dispatchTouchEvent()
方法 - 子 View 又可以是一个
ViewGroup
(比如 LinearLayout),于是子 View 又重复上面的流程:onInterceptTouchEvent()
- 再分发给自己的子 View。
- 就这样,一层一层递归下去,直到遇到一个普通 View(没有子 View 的 Button、TextView),最后交给
onTouchEvent()
来消费。
打个通俗比喻:
- 一个 ViewGroup 就像一个"村长",负责分发任务。
- 它收到任务(MotionEvent)后,会问:
- 我要自己干?(拦截)
- 还是派给手下某个小村民?(子 View)
- 村民又是个小村长(嵌套 ViewGroup)的话,继续往下派。
- 最后一个真正干活的是普通农民(Button/TextView)。
补充个知识点:
onInterceptTouchEvent() 只在 “ACTION_DOWN” 开始时有意义!!
- 因为一旦一个手指 ACTION_DOWN 被拦截了,后续的 ACTION_MOVE / ACTION_UP 事件都跟着这个处理链走。
- 如果
DOWN
没拦截,后面的MOVE/UP
也不会随便切换到拦截。
这叫做 事件的捕获(capture)机制,Android 保证事件流动的一致性。
4. 最后
Android 事件分发是一层层向下传,遇到拦截或者消费就停;否则事件会向上传递,直到有人消费或者丢弃。
还有一个问题,对于没了解过事件分发机制的同学来说,对于事件分发:由外到内,事件消费:由内到外 的理解,可能有些困惑,包括我自己,其实就可以简单理解为 ViewGroup 一个方法把事件分发机制写完,方法中间就是挨个遍历子 View 挨个问,你要不要这个事件(由外到内),都不要的话,我就要了(又回到了 由内到外 ),带着这个理解,去看源码就很容易理解事件分发机制了。
相关文章:
安卓触摸事件分发机制分析
1. 前言 🎯 一句话总结: 触摸事件(TouchEvent)会从 Activity 层开始,按从外到内的方式传递给每一个 ViewGroup/View,直到某个 View 消费(consume) 它,事件传递就会停止…...
Servlet (简单的servlet的hello world程序)
Servlet servlet在20年前左右,是网站开发的一种主力技术. 现在随着时间的推移,Java这个圈子中,逐渐使用spring代替了servlet.现在讲servlet,目的有两个方面. 1.spring作为一个框架.底层仍然是需要调用servlet里的一些api的,包括熟悉servlet有助于理解spring工作原理.包括spr…...
解析 OpenHarmony、HarmonyOS 与 HarmonyOS Next:优雅草卓伊凡的观点
解析 OpenHarmony、HarmonyOS 与 HarmonyOS Next:优雅草卓伊凡的观点 在科技领域,围绕操作系统的讨论从未停歇,其中 OpenHarmony、HarmonyOS 及其后续版本 HarmonyOS Next 备受瞩目。优雅草的卓伊凡对此有着深入见解,在此为大家详…...
Redis03-基础-C#客户端
零、文章目录 Redis03-基础-C#客户端 1、安装NuGet包 dotnet add package Newtonsoft.Json -v 13.0.3 dotnet add package StackExchange.Redis -v 2.8.242、操作帮助类实现 /*** 主题:Redis帮助类 功能:1、设置连接字符串、选择数据库2、String操作…...
JimuBI 积木报表 v1.9.5发布,大屏和仪表盘,免费数据可视化
项目介绍 JimuBI (积木报表BI) 是一款免费的数据可视化产品,含大屏和仪表盘、门户、移动图表,像搭建积木一样完全在线设计! 大屏采用类word风格,可以随意拖动组件,想怎么设计怎么设计,可以像百度和阿里一样…...
有关爬虫中数据库的封装——单线程爬虫
在编写爬虫程序时,数据存储是一个非常重要的环节。尤其是在单线程爬虫中,虽然并发量不大,但如果每次操作数据库都直接连接、查询、关闭,不仅代码臃肿,还容易出错,甚至影响爬虫的稳定性。 因此,…...
React19 useOptimistic 用法
用法 乐观更新 发起异步请求时,先假设请求会成功立即更新 UI 给用户反馈若请求最终失败,再将 UI 恢复到之前的状态 const [optimisticState, addOptimistic] useOptimistic(state, updateFn) 参数 state:实际值,可以是 useSta…...
简单的 shell 程序
整体思路 一个简单的 shell 程序的工作流程如下: 初始化环境:在启动时从系统获取环境变量。循环等待用户输入:不断输出命令行提示符,等待用户输入命令。解析命令:把用户输入的命令解析成可执行的格式。执行命令&…...
MIT XV6 - 1.1 Lab: Xv6 and Unix utilities - sleep
接上文 MIT XV6 - 1. 环境准备 实验正文 打开实验链接 Lab: Xv6 and Unix utilities ,可以看到他一共有6个小实验(头大,让我们争取日拱一卒吧…): Boot xv6 (easy)sleep (easy)pingpong (easy)primes (moderate)/(hard)find (moderate)xargs (moderate…...
测地型GNSS接收机_毫米高精度精准定位
在建筑安全、地灾监测、大坝桥梁隧道监测、工程测绘、国土规划等专业领域,传统工具效率低、精度差、环境适应性弱的痛点长期存在。计讯物联测地型GNSS接收机以毫米级精度、全场景适应、智能互联为核心优势,重新定义高精度空间数据采集标准&#…...
React19源码系列之 root.render过程
在创建react项目的时候,入口文件总是有这样一行代码 root.render(<App />) 所以 root.render() 执行是怎样的? 下面就来看看。 之前的文章就提及,root是一个 ReactDOMRoot 对象,其原型链上有 render 和 unmount 方法。 ReactDOMHy…...
0804标星_复制_删除-网络ajax请求2-react-仿低代码平台项目
文章目录 1 标星2 复制3 假删除4 恢复5 彻底删除结语 1 标星 操作:标星和取消标星,有2种状态的布尔值。通过更新问卷功能实现。 后端quetion.js添加接口 {// 更新问卷信息url: /api/question/:id,method: patch,response() {return {errno: 0}}},前端q…...
二叉树遍历(C语言版)
前序遍历创建树,中序遍历把创建出来的二叉树的结点打印出来 题目链接:牛客网-二叉树遍历 前序遍历创建树的思想: 把每个结点看作是子树的根节点,以根左右的顺序创建一整棵二叉树 1.空 返回空 2.非空 先是malloc一个结点ÿ…...
OceanBase数据库-学习笔记2-C#/C++程序如何访问
MySQL模式下,程序(C#)连接数据库操作demo SqlSugar public class MainModel {private static readonly ConnectionConfig connectionConfig new ConnectionConfig(){ConnectionString "serverxxx.xxx.xxx.xxx;port2881;user idroot;…...
Python中的Walrus运算符分析
Python中的Walrus运算符(:)是Python 3.8引入的一个新特性,允许在表达式中同时赋值和返回值。它的核心作用是减少重复计算,提升代码简洁性。以下是其适用的典型场景及示例: 1. 在循环中避免重复计算 当循环条件需要多次…...
【深度好文】4、Milvus 存储设计深度解析
引言 作为一款主流的云原生向量数据库,Milvus 通过其独特的存储架构设计来保证高效的查询性能。本文将深入剖析 Milvus 的核心存储机制,特别是其最小存储单元 Segment 的完整生命周期,包括数据写入、持久化、合并以及索引构建等关键环节。 …...
航顺 芯片 开发记录 (一) 2025年4月27日19:23:32
芯片型号: HK32F030MF4P6 第一步:创建工程目录 inc :头文件目录 MDK-ARM : 工程根目录 (新建工程选择该目录) src :相关资源存放位置 官方函数库相关内容 官方函数库大致结构图 ├─HK32F030MLib ├─CMSIS │ ├─CM0 │ │ └─Core │ │ arm_common_table…...
Java 设计模式
Java后端常用设计模式总览表 模式核心思想Spring / Spring Boot应用手写实现核心单例模式 (Singleton)一个类只有一个实例,提供全局访问点Spring容器中的默认Bean都是单例管理volatile synchronized 双重检查锁定,懒加载单例工厂模式 (Factory)统一管理…...
Milvus如何实现关键词过滤和向量检索的混合检索
Milvus 可以实现关键词过滤和向量检索的混合检索,具体来说,可以结合向量搜索与其他属性字段(如关键词、类别标签等)进行联合查询。这样,在检索时不仅考虑向量的相似度,还能根据特定的关键词或标签等条件对数据进行筛选,从而提高检索的精度和灵活性。 1. 理解混合检索的…...
基于Qt5的蓝牙打印开发实战:从扫描到小票打印的全流程
文章目录 前言一、应用案例演示二、开发环境搭建2.1 硬件准备2.2 软件配置 三、蓝牙通信原理剖析3.1 实现原理3.2 通信流程3.3 流程详解3.4 关键技术点 四、Qt蓝牙核心类深度解析4.1 QBluetoothDeviceDiscoveryAgent4.2 QBluetoothDeviceInfo4.3 QBluetoothSocket 五、功能实现…...
Linux日志处理命令多管道实战应用
全文目录 1 日志处理1.1 实时日志分析1.1.1 nginx日志配置1.1.2 nginx日志示例1.1.3 日志分析示例 1.2 多文件合并分析1.3 时间范围日志提取 2 问题追查2.1 进程级问题定位2.2 网络连接排查2.3 硬件故障追踪 3 数据统计3.1 磁盘空间预警3.2 进程资源消耗排名3.3 HTTP状态码统计…...
Node.js CSRF 保护指南:示例及启用方法
解释 CSRF 跨站请求伪造 (CSRF/XSRF) 是一种利用用户权限劫持会话的攻击。这种攻击策略允许攻击者通过诱骗用户以攻击者的名义提交恶意请求,从而绕过我们的安全措施。 CSRF 攻击之所以可能发生,是因为两个原因。首先,CSRF 攻击利用了用户无法辨别看似合法的 HTML 元素是否…...
线性代数—向量与矩阵的范数(Norm)
参考链接: 范数(Norm)——定义、原理、分类、作用与应用 - 知乎 带你秒懂向量与矩阵的范数(Norm)_矩阵norm-CSDN博客 什么是范数(norm)?以及L1,L2范数的简单介绍_l1 norm-CSDN博客 范数(Norm…...
微服务基础-Ribbon
1. Ribbon简介: 客户端的负载均衡: 2....
移除生产环境所有console.log
大多数团队都会要求不能在生产环境输出业务侧的内容,但是往往业务开发人员会有疏漏,所以需要在工程化环境中,整体来管理console.log。我最近也是接到这样一个需求,整理了一下实现方案。 不同团队,不同场景,…...
数字人接大模型第二步:实时语音同步
接上例第一步,还是dh_live项目,增加了一个完整的实时对话样例,包含vad-asr-llm-tts-数字人全流程,以弥补之前的只有固定的问答的不足。 VAD(Voice Activity Detection,语音活动检测)VAD用于检测用户是否正在说话,从而触发后续的语音处理流程。 ASR(Automatic Speech R…...
Tomcat的安装与配置
Tomcat Tomcat是一个Java圈子中广泛使用的HTTP服务器. 后续学习Severlet内容,就是依赖Tomcat. Java程序员,要想写个网站出来,绕不开Tomcat. 我们这里使用Tomcat8 在bin目录下,这两个文件尤为重要,需要说明的是,Tomcat是那Java写的,所以在运行时需要jdk. bat后缀:是Window…...
Spring AI Alibaba - MCP连接 MySQL
先看效果 直接问他数据库有什么表。 大模型调用MySQL进行查询 搭建项目 添加依赖 创建项目后新添加Maven 依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> …...
Spring Cloud Stream喂饭级教程【搜集全网资料整理】
文章较长,建议收藏关注,随时查看 Spring Cloud Stream 简介 Spring Cloud Stream 是 Spring 提供的一个框架,用于构建与共享消息系统相连接的高度可伸缩的事件驱动微服务,它建立在 Spring 已有的成熟组件和最佳实践之上ÿ…...
prometheus手动添加k8s集群外的node-exporter监控
1、部署node-exporter 1)helm方式部署 rootiZj6c72dzbei17o2cuksmeZ:~# helm repo add prometheus-community https://prometheus-community.github.io/helm-charts "prometheus-community" has been added to your repositories rootiZj6c72dzbei17o2cu…...
Linux(Centos版本)中安装Docker
文章目录 Linux(Centos版本)中安装Docker整体流程 Linux(Centos版本)中安装Docker整体流程 进入root权限进行安装: 下面开始安装Docker: 1、安装docker的yum管理工具:记得将yum仓库更改为国内的镜像源&…...
C语言-- 深入理解指针(4)
C语言-- 深入理解指针(4) 一、回调函数二、冒泡排序三、qsort函数3.1 使用qsort函数排序整型数据3.2 使用qsort函数排序double数据3.3 使用qsort来排序结构体数据 四、模仿qsort库函数实现通用的冒泡排序4.1 通用冒泡排序函数排序整型数据4.2 通用冒泡排…...
牟乃夏《ArcGIS Engine地理信息系统开发教程》学习笔记3-地图基本操作与实战案例
目录 一、开发环境与框架搭建 二、地图数据加载与文档管理 1. 加载地图文档(MXD) 2. 动态添加数据源 三、地图浏览与交互操作 1. 基础导航功能 2. 书签管理 3. 量测功能 四、要素选择与属性查询 1. 属性查询 2. 空间查询 五、视图同步与鹰眼…...
Spark Streaming实时数据处理实战:从DStream基础到自定义数据源集成
park-Streaming概述 Spark-Streaming是什么 Spark Streaming 用于流式数据的处理。Spark Streaming 支持的数据输入源很多,例如:Kafka、Flume、Twitter等,以及和简单的 TCP 套接字等等。数据输入后可以用 Spark 的高度抽象原语如:…...
微软GraphRAG的安装和在RAG中的使用体会
文章目录 0. 简介(1)**技术原理**(2)**优势**(3)**开源与演进** 1. 下载graphrag.git2.安装 poetry3.初始化项目:建立cases目录4. 修改.env5.修改settings.yaml,将两处 api_base改成中转站地址:…...
Python学习记录7——集合set()的使用指南
文章目录 引言一、集合特性二、创建方式三、元素操作1、添加元素(1)add(element)(2)update(iterables) 2、删除元素(1)remove(element)(2)discard(element)(3)…...
apkpure 谷歌插件 下载的apk包
谷歌插件市场搜索 apkpure 然后直接搜索下载就行了 想看apk包中的静态资源,直接改apk 为zip后缀解压就行了 apple的ipa包也是相同的道理...
Android四大核心组件
目录 一、为什么需要四大组件? 二、Activity:看得见的界面 核心功能 生命周期图解 代码示例 三、Service:看不见的劳动者 两大类型 生命周期对比 注意陷阱 四、BroadcastReceiver:消息传递专员 两种注册方式 广播类型 …...
WSL2里手动安装Docker 遇坑
在 WSL2 里手动安装 Docker Engine 时遇坑:systemctl 和 service 命令在默认的 WSL2 Ubuntu 中 无法使用,因为 WSL2 没有 systemd。怎么办? 自己操作让 Docker Engine(dockerd)直接跑起来,挂到 /var/run/do…...
【ROS2】ROS开发环境配置——vscode和git
古月21讲-ROS2/1.系统架构/1.5_ROS2开发环境配置/ ROS机器人开发肯定离不开代码编写,课程中会给大家提供大量示例源码,这些代码如何查看、编写、编译 安Linux中安装装git sudo apt install git下载教程源码 《ROS2入门21讲》课程源码的下载方式&#x…...
django.db.models.query_utils.DeferredAttribute object
在 Django 中,当你看到 django.db.models.query_utils.DeferredAttribute 对象时,通常是因为你在查询时使用了 only() 或 defer() 方法来延迟加载某些字段。这两个方法允许你控制数据库查询中的字段加载方式,从而优化查询性能。 only() 方法…...
Linux内核中的编译时安全防护:以网络协议栈控制块校验为例
引言:内存安全的无声守卫者 在操作系统内核开发中,内存溢出引发的错误往往具有极高的隐蔽性和破坏性。Linux内核作为承载全球数十亿设备的基石,其网络协议栈的设计尤其注重内存安全性。本文通过分析一段看似简单的内核代码,揭示Linux如何通过编译时静态检查(Compile-Time…...
第11章 安全网络架构和组件(一)
11.1 OSI 模型 协议可通过网络在计算机之间进行通信。 协议是一组规则和限制,用于定义数据如何通过网络介质(如双绞线、无线传输等)进行传输。 国际标准化组织(ISO)在20世纪70年代晚期开发了开放系统互连(OSI)参考模型。 11.1.1 OSI模型的…...
Git常用命令简明教程
本教程整合并优化了Git核心命令,涵盖初始化、配置、文件操作、分支管理、远程仓库操作及常见场景,适合快速入门和日常参考。命令按使用流程分组,简洁明了,包含注意事项和最佳实践。 1. 初始化与配置 初始化Git仓库并设置基本配置…...
在 Ubuntu 24.04 系统上安装和管理 Nginx
1、安装Nginx 在Ubuntu 24.04系统上安装Nginx,可以按照下面的步骤进行: 1.1、 更新系统软件包列表 在安装新软件之前,需要先更新系统的软件包列表,确保获取到最新的软件包信息。打开终端,执行以下命令: …...
数据结构——二叉树和堆(万字,最详细)
目录 1.树 1.1 树的概念与结构 1.2 树相关的术语 1.3 树的表示法 2.二叉树 2.1 概念与结构 2.2 特殊的二叉树 2.2.1 满二叉树 2.2.2 完全二叉树 2.3 二叉树存储结构 2.3.1 顺序结构 2.3.2 实现顺序结构二叉树 2.3.2.1 堆的概念与结构 2.3.2. 2 堆的插入与删除数据…...
IdeaVim 配置与使用指南
一、什么是 IdeaVim? IdeaVim 是 JetBrains 系列 IDE(如 IntelliJ IDEA, WebStorm, PyCharm 等)中的一个插件,让你在 IDE 里使用 Vim 的按键习惯,大大提升效率。 安装方法: 在 IDE 中打开 设置(Settings) →…...
前端浏览器窗口交互完全指南:从基础操作到高级控制
浏览器窗口交互是前端开发中构建复杂Web应用的核心能力,本文深入探讨23种关键交互技术,涵盖从传统API到最新的W3C提案,助您掌握跨窗口、跨标签页的完整控制方案。 一、基础窗口操作体系 1.1 窗口创建与控制 // 新窗口创建(现代浏…...
考研系列-计算机组成原理第五章、中央处理器
一、CPU的功能及结构 1.运算器的基本结构 2.控制器结构...
python+flask+flask-sockerio,部署后sockerio通信异常
前言 用python开发了一个flask web服务,前端用html,前后端通过socketio通信,开发环境,windowsminicondavscode,开发完成后本地运行没有问题,然后就开始部署,噩梦就开始了。 问题描述 程序是部…...