11、事件分发目标查找:findFocusedWindowTargets()与findTouchedWindowTargets()
11.1 为什么需要两个查找方法你想想看键盘事件和触摸事件的性质完全不同。键盘事件用户按下一个键系统得知道当前哪个窗口获得了焦点。焦点窗口只有一个所以查找逻辑相对简单。触摸事件用户手指点下去系统得知道手指落在哪个窗口上。可能有多个窗口重叠还得考虑窗口的可见区域、是否可点击等等。所以Android把这两种查找逻辑分开了。一个管焦点一个管触摸。嗯这里要注意触摸事件的分发远比键盘事件复杂我在项目中遇到过好几次因为触摸目标找错导致的诡异Bug后面会细说。11.2 findFocusedWindowTargets()焦点窗口的查找这个方法的核心任务找到当前拥有输入焦点的窗口然后把事件发过去。我们先看它的简化流程// 伪代码展示核心逻辑 void findFocusedWindowTargets() { // 1. 获取当前焦点窗口 spInputWindowHandle focusedWindow findFocusedWindow(); // 2. 检查焦点窗口是否有效 if (focusedWindow nullptr) { // 没有焦点窗口丢弃事件 return; } // 3. 检查窗口是否已死亡 if (focusedWindow-getInputChannel() nullptr) { // 窗口已销毁丢弃事件 return; } // 4. 检查窗口是否可接收事件 if (!focusedWindow-canReceiveInput()) { // 窗口不可接收输入丢弃事件 return; } // 5. 添加到目标列表 mTargets.add(focusedWindow); }看起来很简单对吧但实际源码里要考虑的细节远不止这些。我记得有一次调试一个第三方输入法的问题发现按键事件总是丢失最后定位到就是findFocusedWindow()返回了nullptr——因为焦点窗口在事件到达前刚好被销毁了。关键点焦点窗口的查找依赖于WindowManagerService维护的焦点栈。每次窗口焦点变化时WMS都会通过InputManagerService通知InputDispatcher更新焦点信息。11.3 findTouchedWindowTargets()触摸窗口的查找这个方法就复杂多了。触摸事件的目标查找说白了就是根据触摸点的坐标找到最合适的那个窗口。我们来看核心流程// 伪代码展示核心逻辑 void findTouchedWindowTargets() { // 1. 获取所有可见窗口 VectorspInputWindowHandle windows getVisibleWindows(); // 2. 按Z-order排序从上到下 sortWindowsByZOrder(windows); // 3. 遍历窗口找到第一个包含触摸点的窗口 for (auto window : windows) { // 3.1 检查窗口是否可触摸 if (!window-canReceiveTouch()) continue; // 3.2 检查触摸点是否在窗口区域内 if (!window-containsPoint(touchX, touchY)) continue; // 3.3 检查窗口是否被遮挡 if (isWindowObscured(window)) continue; // 3.4 找到了添加到目标列表 mTargets.add(window); break; } // 4. 如果没找到检查是否有壁纸窗口 if (mTargets.isEmpty()) { handleTouchOnWallpaper(); } }这里有几个坑我一个个说。11.3.1 窗口遮挡检测你想想看如果两个窗口重叠了上面的窗口是透明的那触摸事件应该发给谁Android的处理方式是默认发给最上面的窗口。但如果上面的窗口设置了FLAG_NOT_TOUCHABLE或者FLAG_NOT_TOUCH_MODAL那事件就会穿透到下面的窗口。避坑指南我曾经遇到过一个Bug弹窗挡住了底部的按钮但弹窗本身设置了透明背景且没有消费触摸事件。结果用户点击弹窗区域事件穿透到了底部的按钮上。解决方案就是给弹窗设置FLAG_NOT_TOUCH_MODAL并正确处理事件拦截。11.3.2 触摸区域的计算窗口的触摸区域不仅仅是它的布局边界。还要考虑裁剪区域父窗口可能对子窗口进行裁剪圆角裁剪某些窗口有圆角效果安全区域刘海屏、挖孔屏的避让区域我记得有一次调试一个全面屏手机的触摸问题用户点击屏幕边缘总是没反应。查了半天发现是安全区域的计算出了问题触摸点被判定为在安全区域之外导致事件被丢弃。11.4 两个方法的协作关系你可能要问了这两个方法会不会同时被调用答案是会但分场景。事件类型调用的方法说明按键事件KeyEventfindFocusedWindowTargets()发给焦点窗口触摸事件MotionEventfindTouchedWindowTargets()发给触摸点下的窗口轨迹球事件两者都可能取决于具体实现嗯这里要注意触摸事件的分发优先级高于焦点事件。什么意思呢比如用户正在触摸一个窗口这时候来了一个按键事件按键事件还是会发给焦点窗口而不是触摸窗口。两者互不干扰。11.5 源码中的关键数据结构这两个方法操作的核心数据结构是InputTarget。每个InputTarget代表一个事件的目标窗口包含struct InputTarget { // 目标窗口的输入通道 spInputChannel inputChannel; // 标志位FLAG_FOREGROUND, FLAG_WALLPAPER等 uint32_t flags; // 全局缩放比例用于多窗口模式 float globalScaleFactor; // 窗口的变换矩阵 const InputWindowHandle* windowHandle; };我个人习惯在调试时重点关注flags字段。它决定了事件是以什么方式发送给窗口的——是前台分发还是后台分发是否需要壁纸处理等等。11.6 实战经验总结最后分享几个我在项目中踩过的坑焦点窗口丢失快速切换Activity时焦点窗口可能短暂为null。解决方案是在findFocusedWindowTargets()里加一个重试机制。触摸穿透Dialog或PopupWindow没有正确设置FLAG_NOT_TOUCH_MODAL导致事件穿透到下层窗口。多指触摸多点触控时每个手指的触摸点可能落在不同窗口上。Android的处理方式是第一个手指决定目标窗口后续手指都发给同一个窗口。调试技巧如果你想观察事件分发的目标窗口可以在InputDispatcher的日志里搜索findFocusedWindow或findTouchedWindow。开启adb shell dumpsys input也能看到当前窗口的焦点状态和触摸区域信息。好了这一章我们详细拆解了findFocusedWindowTargets()和findTouchedWindowTargets()的内部逻辑。下一章我们会继续深入看看事件找到目标窗口之后是怎么通过InputChannel发送过去的。到时候我会重点讲一讲跨进程通信的细节那也是很多性能问题的根源所在。

相关新闻

Lighthouse 绿分不代表真实体验:CrUX 现场数据与实验室数据的口径差异解读

Lighthouse 绿分不代表真实体验:CrUX 现场数据与实验室数据的口径差异解读

Lighthouse 绿分不代表真实体验:CrUX 现场数据与实验室数据的口径差异解读适用读者:做外贸独立站、在意 Google 收录与排名的开发者和站长;正在用 Lighthouse 和 PageSpeed Insights 给站点做性能体检,但发现分数跟海外用户反馈对…

2026/10/8 7:25:12 阅读更多 →
Python Agent 踩坑实录:第一次写 Agent,我忘了加一行代码,循环跑了 200 次

Python Agent 踩坑实录:第一次写 Agent,我忘了加一行代码,循环跑了 200 次

Python Agent 踩坑实录:第一次写 Agent,我忘了加一行代码,循环跑了 200 次 摘要:本文从一次"初学者写 Agent 忘了加最大步数限制、循环跑了 200 次才停"的经历出发,分析 Agent 循环失控的三个常见原因&#…

2026/10/8 7:25:12 阅读更多 →
工业级电源路径保护:TPS259483AYWPR与STM32F405ZG协同设计

工业级电源路径保护:TPS259483AYWPR与STM32F405ZG协同设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 7:25:12 阅读更多 →

最新新闻

PP-TTS 语音合成模型下载与部署实践:FastSpeech2 声学模型与 HiFiGAN 声码器的获取、推理与 Benchmark 全指南

PP-TTS 语音合成模型下载与部署实践:FastSpeech2 声学模型与 HiFiGAN 声码器的获取、推理与 Benchmark 全指南

人工智能深度学习计算机视觉NLP语音 【免费下载链接】models Officially maintained, supported by PaddlePaddle, including CV, NLP, Speech, Rec, TS, big models and so on. 项目地址: https://gitcode.com/gh_mirrors/mo/models 点击查看 免费下载 PP-TTS 是飞…

2026/10/8 7:53:17 阅读更多 →
Qwen-Image-2.1云端部署实战:A10 GPU+Docker+OSS生产级架构

Qwen-Image-2.1云端部署实战:A10 GPU+Docker+OSS生产级架构

1. 这不是“跑个模型”那么简单:Qwen-Image-2.1 云端部署的真实门槛在哪里你搜到“Qwen-Image-2.1 云端部署”这八个字时,大概率正站在两个现实之间摇摆:一边是本地显卡不够、显存爆掉、连模型权重都下不全的挫败感;另一边是点开阿…

2026/10/8 7:53:17 阅读更多 →
Kylin V10 ARM64部署K8S 1.26.15:外部etcd+containerd离线实践

Kylin V10 ARM64部署K8S 1.26.15:外部etcd+containerd离线实践

简介:本资源是一套面向国产化信创环境的Kubernetes高可用部署实践合集,专为ARM架构下Kylin V10操作系统用户设计,解决在无内置etcd、依赖外部etcd集群场景中使用containerd容器运行时部署K8s 1.26.15(一主多从)的核心难…

2026/10/8 7:53:17 阅读更多 →
在线游戏云系统模型与方程式:从延迟预算到容量规划

在线游戏云系统模型与方程式:从延迟预算到容量规划

1. 为什么在线游戏需要一套“系统模型”在线游戏云化这件事,喊了也有七八年了。早期大家理解的“云游戏”就是把游戏跑在服务器上,画面推流到客户端,玩家本地不渲染、不运算。这个思路本身没问题,但真正落到工程上会发现一系列连锁…

2026/10/8 7:53:16 阅读更多 →
WebGPU端侧视频修复模型轻量化实战:从云端大模型到浏览器实时推理

WebGPU端侧视频修复模型轻量化实战:从云端大模型到浏览器实时推理

1. 从云端到端侧:视频修复模型轻量化的核心命题视频修复这件事,过去几年一直是云端大模型的专属领地。Wink 这类云端视频修复服务,背后跑的是动辄几十亿参数的超分重建网络,一张 1080P 的帧要经过多尺度特征提取、光流对齐、时序融…

2026/10/8 7:53:14 阅读更多 →
Superpowers技能包:为Claude Code注入工程化开发流程

Superpowers技能包:为Claude Code注入工程化开发流程

不知道你有没有过这种感觉:Claude Code确实能干活,可一旦任务稍微复杂一点,它就很容易“急着给答案”。我前阵子接手一个遗留项目,需求本身不大,但它上来就给我甩了一段能跑的代码,也没解释业务边界&#x…

2026/10/8 7:52:14 阅读更多 →

日新闻

抖音用户主页视频数据爬虫详解:点赞、收藏、分享字段抓取与 TaoToken 统一 Key 配置

抖音用户主页视频数据爬虫详解:点赞、收藏、分享字段抓取与 TaoToken 统一 Key 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 0:00:03 阅读更多 →
AI 编程 Trae 国内版与国际版一篇讲透:TaoToken 统一 Key 接入实测

AI 编程 Trae 国内版与国际版一篇讲透:TaoToken 统一 Key 接入实测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 0:00:06 阅读更多 →
Claude Desktop 配置第三方推理接口教程:用 TaoToken 统一 Key 打通 API 调用

Claude Desktop 配置第三方推理接口教程:用 TaoToken 统一 Key 打通 API 调用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 0:00:07 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:34:12 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:34:13 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 9:29:10 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:34:12 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 11:43:46 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 13:34:55 阅读更多 →