15、拦截器Interceptor:InputFilter与InputMonitor的工作原理,事件窃听与修改

发布时间:2026/10/8 6:48:10

15、拦截器Interceptor:InputFilter与InputMonitor的工作原理,事件窃听与修改 15.1 InputFilter系统级的事件过滤器先说说InputFilter。它是个什么东西说白了它就是一个可以插入到事件分发管道里的过滤器。你想想看所有触摸事件、按键事件在到达目标窗口之前都会先经过它手里过一遍。核心要点InputFilter运行在system_server进程里它有权决定事件是放行、修改还是直接吃掉。我记得在做一个安全项目时需要拦截所有应用的截屏按键。当时我就在想如果每个应用都去监听按键那太不靠谱了。后来发现InputFilter正好干这个——在系统层面统一拦截。来看一下它的工作流程// InputFilter.java 核心方法 Override public void filterInputEvent(InputEvent event, int policyFlags) { if (event instanceof KeyEvent) { KeyEvent keyEvent (KeyEvent) event; // 我习惯在这里先判断事件类型 if (keyEvent.getKeyCode() KeyEvent.KEYCODE_VOLUME_UP) { // 直接吃掉不让往下传 return; // 不调用super事件就消失了 } // 或者修改事件 KeyEvent modifiedEvent KeyEvent.changeFlags(keyEvent, keyEvent.getFlags() | KeyEvent.FLAG_CANCELED); super.filterInputEvent(modifiedEvent, policyFlags); return; } super.filterInputEvent(event, policyFlags); }这里有个坑我曾经踩过如果你在filterInputEvent里不调用super.filterInputEvent()事件就被你“私吞”了。系统不会报错但所有窗口都收不到这个事件。调试时我找了半天还以为是驱动问题。警告InputFilter的修改会影响所有应用。如果你不小心把HOME键给过滤了用户就回不了桌面了。我曾经在测试机上干过这事最后只能adb重启。15.2 InputMonitor窗口级的监控者接下来是InputMonitor。这个家伙和InputFilter不同它不修改事件它只偷听。你想想看有时候我们想知道某个窗口收到了什么事件但又不想影响它正常处理怎么办InputMonitor就是干这个的。我个人习惯把InputMonitor理解成“事件窃听器”。它注册到InputDispatcher里当事件被派发给目标窗口时它会收到一份拷贝。注意是拷贝不是原件。特性InputFilterInputMonitor运行位置system_serversystem_server能否修改事件能不能能否拦截事件能不传递即可不能典型用途系统级按键屏蔽、手势修改录屏、无障碍、调试为什么会需要InputMonitor举个例子录屏应用需要记录用户的触摸轨迹。如果它自己去监听每个窗口的触摸事件那得侵入多少代码有了InputMonitor它只需要在系统注册一个监控器所有事件都会“路过”它这里。15.3 事件窃听的实现原理咱们深入一点看看InputMonitor是怎么“偷听”的。在InputDispatcher的源码里有一个关键的数据结构// InputDispatcher.cpp class InputDispatcher : public Thread { // 监控器列表 VectorspInputMonitor mMonitors; void dispatchOnce() { // ... 获取事件 for (const auto monitor : mMonitors) { // 给每个监控器发一份拷贝 monitor-notifyInputEvent(event); } // 然后才派发给目标窗口 dispatchToTarget(event, target); } };看到没先通知监控器再派发给窗口。这个顺序很重要。监控器收到的是事件拷贝所以它修改不了原始事件。但如果你在监控器里做了一些耗时操作比如写日志、网络请求那就会拖慢整个事件分发。提示我曾经在InputMonitor的回调里做了文件IO操作结果导致触摸明显卡顿。后来改成异步处理问题就解决了。记住监控器回调里千万别做耗时操作。15.4 实战如何实现一个自定义拦截器好了理论说完了咱们来点实际的。假设你现在需要实现一个功能在游戏模式下屏蔽所有虚拟按键。你会怎么做嗯我的做法是写一个自定义InputFilterpublic class GameModeInputFilter extends InputFilter { private boolean mGameModeEnabled false; public GameModeInputFilter(InputFilterHost host) { super(host); } Override public void filterInputEvent(InputEvent event, int policyFlags) { if (!mGameModeEnabled) { super.filterInputEvent(event, policyFlags); return; } if (event instanceof KeyEvent) { KeyEvent keyEvent (KeyEvent) event; int keyCode keyEvent.getKeyCode(); // 虚拟按键列表返回、菜单、主页、最近任务 if (keyCode KeyEvent.KEYCODE_BACK || keyCode KeyEvent.KEYCODE_MENU || keyCode KeyEvent.KEYCODE_HOME || keyCode KeyEvent.KEYCODE_APP_SWITCH) { // 直接吃掉不传递 return; } } // 其他事件正常放行 super.filterInputEvent(event, policyFlags); } public void setGameMode(boolean enabled) { mGameModeEnabled enabled; } }然后通过InputManager注册InputManager im (InputManager) getSystemService(Context.INPUT_SERVICE); im.registerInputFilter(new GameModeInputFilter(host));这里要注意注册InputFilter需要系统权限。普通应用是调不了这个API的。我记得当时为了在普通应用里实现类似效果只能走无障碍服务那条路但效果差很多。15.5 两者的协作与区别最后总结一下。InputFilter和InputMonitor虽然都叫拦截器但定位完全不同InputFilter像门卫能决定谁进谁出还能给人换衣服修改事件。InputMonitor像监控摄像头只看不碰记录一切。在实际项目中我建议你这样选择需要阻止或修改事件 → 用InputFilter只需要观察或记录事件 → 用InputMonitor两者都用可以但要注意顺序InputFilter先处理InputMonitor后观察。避坑指南我曾经在同一个项目里同时用了InputFilter和InputMonitor结果InputFilter把事件拦截了InputMonitor就收不到。因为InputMonitor是在事件被派发后才通知的。如果你既想拦截又想监控记得在InputFilter里手动通知监控器。好了这一章的内容就到这里。拦截器这部分虽然代码量不大但理解透彻了对掌握整个Input系统的灵活性很有帮助。
延伸阅读

更多相关文章

2026/10/8 6:48:10

超帧:广义相对论中如何定义“此刻”的时空切片方法

第一次见到 hyperframe 这个词,是在一份数值相对论的代码注释里。当时我正找“超曲面切片”的正确实现,注释里只写了一句话:compute the normal of this hyperframe。教科书索引里几乎找不到这个词,它更像是做引力模拟的人随手给出…

2026/10/8 6:43:10

eFuse+MCU电源路径保护方案:选型、参数计算与固件状态机

1. 项目解读:用一颗eFuse加一颗MCU,把电源路径保护做成可管理的系统工程嵌入式开发越往后做,越会碰到一个很扎心的现实:功能做得再好,电源一抖,全部归零。工业场景尤其如此,现场总线的浪涌、接插…

2026/10/8 6:43:10

day07 张益瑄 (笔记)

主轴对齐方式 属性名: justify-content常用值如下: flex-start :主轴起点对齐。—— 默认值flex-end :主轴终点对齐。center :居中对齐space-between :均匀分布,两端对齐(最常用&a…

2026/10/8 7:48:14

Agent Skills工程化:可验证、可组合、可观测的最小执行单元

1. 这不是“技能列表”,而是一套可执行、可组合、可验证的工程化能力单元你搜“skills”时看到的满屏“Claude skills”“agent skills”“superpower skills”,绝大多数人第一反应是:这不就是个功能菜单?点一下就能用的插件&…

2026/10/8 7:48:14

openrig:本地大模型推理编排框架的显存优化与多模型调度实战

1. openrig的真实定位:一个能“编排”大模型的本地推理框架上个月做内部技术分享,我需要同时演示两个本地模型:一个专攻代码生成,一个做通用对话。放在以前,我用的方案是这样的——先杀掉当前进程,卸载模型…

2026/10/8 7:48:14

context-mode实战:多项目并行开发的上下文管理方案

1. context-mode到底解决什么问题:从一个让我崩溃的下午说起我先说个真实经历。两年前我手里同时压着三个项目:一个订单服务要重构,一个数据报表要接新BI,还有一个老项目要修线上紧急bug。每天上午的第一个动作不是写代码&#xf…

2026/10/8 7:48:14

OpenRig:本地AI工作流调度器,多模型服务一键切换

1. OpenRig 是什么:一个被误读但极具潜力的本地 AI 工作流调度器OpenRig 这个名字最近在开发者社区里频繁出现,但它既不是某个新发布的闭源商业产品,也不是某家大厂推出的 AI 框架——它本质上是一个轻量级、可组合、面向本地 AI 开发者的工作…

2026/10/8 7:48:14

AI技能插件实战:打造Ponytail马尾辫造型决策工具

提到 ponytail,很多人第一反应就是“马尾辫嘛,谁不会扎”。但真正上手之后你会发现,远不是那回事——同一个马尾,扎高一点、低一点、松一点、紧一点,视觉效果天差地别。我前后折腾了大半年,试过无数教程&am…

2026/10/8 7:43:13

CTF杂项解题exe工具链全攻略:从文件识别到内存取证

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

2026/10/5 6:32:56

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/7 8:18:33

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/8 6:05:44

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* 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:02:17

自然数立方等于连续奇数之和:从证明到编程验证

十几年来我一直游走在数学科普和编程教学这两块内容之间,对“看起来像魔法、拆开全是数学”的结论总是格外敏感。最近翻资料时又撞见一句话:任何一个自然数 m 的立方,都可以写成 m 个连续奇数之和。2 的立方等于 3 加 5,3 的立方等…

2026/10/8 0:02:17

C#上位机SSH连接实战:用SSH.NET补齐超时、批量与密钥认证

简介:这是一份基于 C# 开发的 SSH 连接功能半成品工程,原本作为另一个主项目的子功能模块,现独立打包分享。工程采用 WinForms 界面,包含源码、解决方案、安装部署工程、NuGet 依赖包及说明文档,适合正在做远程连接、网…

2026/10/8 0:02:17

Java SpringBoot一体化智能售后系统设计与实现全解析

毕业设计年年做,Java Web 方向的题目翻来覆去就那么几个,但“一体化智能售后系统”这个题,每次看到我都觉得值得认真聊一聊。它不是一个简单 curd 堆出来的管理系统,而是把客户、工单、派单、处理、回访、统计整条链路串起来的一套…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑