Android 7系统无障碍服务(一)全景图与架构概览 📅 2026/8/27 12:35:51 系列目录第一篇全景图与架构概览 | 第二篇AccessibilityManagerService 启动与初始化 | 第三篇无障碍服务的注册与绑定 | 第四篇AccessibilityEvent 的产生与投递 | 第五篇AccessibilityNodeInfo 的构建与查询 | 第六篇输入事件拦截与 TouchExplorer | 第七篇手势分发与 KeyEvent 处理 | 第八篇放大镜与辅助功能特性一、为什么要学无障碍服务TalkBack 是怎么在用户触摸屏幕时读出控件内容的自动化测试框架又是怎样跨进程查到某个 View 并对它执行点击的无障碍服务明明运行在自己进程里为什么能拦截系统级的触摸和按键事件这些问题的答案都指向同一个模块——Android 无障碍服务AccessibilityService。它是一个系统级 Service能够监听系统范围内 UI 变化事件AccessibilityEvent、查询窗口内控件树结构AccessibilityNodeInfo、拦截和注入输入事件甚至执行控件动作如点击、滑动。典型应用场景包括 TalkBack屏幕阅读器、自动化测试框架、辅助功能 App 等。从源码视角看无障碍服务模块横跨了 View 层、Framework 客户端、Framework 服务端、输入系统等多个层次涉及的类多达二十余个是一条非常完整的跨进程调用链路。本文作为系列开篇将先从整体上梳理无障碍服务的架构分层、核心类关系以及三条主干数据流为后续各篇的深入分析建立一个全局地图。二、整体架构分层AOSP 7 中无障碍服务相关的代码分布如下图所示┌────────────────────────────────────────────────────┐ │ 应用层 │ │ MyAccessibilityService extends AccessibilityService │ │ AndroidManifest.xml (权限 meta-data 声明) │ └────────────────────┬───────────────────────────────┘ │ Binder IPC ┌────────────────────┴───────────────────────────────┐ │ Framework 客户端层 │ │ AccessibilityManager (单例, 事件发送 状态查询) │ │ AccessibilityInteractionClient (节点查询客户端) │ └────────────────────┬───────────────────────────────┘ │ Binder IPC ┌────────────────────┴───────────────────────────────┐ │ Framework 服务端层 │ │ AccessibilityManagerService (AMS, 核心总管) │ │ ├── 服务管理: 注册/绑定/生命周期 │ │ ├── 事件投递: 接收 AccessibilityEvent 并分发 │ │ ├── 输入拦截: 注册 AccessibilityInputFilter │ │ └── 放大镜: MagnificationController │ └─────┬──────────────────┬───────────────────────────┘ │ │ │ (InputFilter) │ (WindowManagerService) ▼ ▼ ┌──────────────┐ ┌───────────────────────────────────┐ │ 输入系统层 │ │ View / 窗口层 │ │ InputManager │ │ View.onInitializeAccessibility- │ │ → Input- │ │ NodeInfo() (节点构建) │ │ Filter │ │ View.sendAccessibilityEvent() │ │ (native) │ │ (事件产生) │ │ → Access- │ │ ViewRootImpl (IAccessibility- │ │ ibility- │ │ InteractionConnection) │ │ InputFilter │ │ WindowManagerService │ └──────┬───────┘ └───────────────────────────────────┘ │ ▼ ┌──────────────────┐ │ EventStream- │ │ Transformation │ │ ├ TouchExplorer │ │ ├ KeyEvent- │ │ │ Dispatcher │ │ └ MotionEvent- │ │ Injector │ └──────────────────┘架构分为五层应用层开发者继承AccessibilityService在 Manifest 中通过BIND_ACCESSIBILITY_SERVICE权限和android.accessibilityservice的 intent-filter 声明由系统进程完成绑定和生命周期管理。Framework 客户端层运行在普通 App 进程或 AccessibilityService 进程中提供两个核心客户端入口——AccessibilityManager负责事件的发送和全局状态的查询AccessibilityInteractionClient负责对控件树的跨进程查询。Framework 服务端层以AccessibilityManagerService为中心运行在 system_server 进程中。它是整个无障碍功能的中枢负责服务绑定管理、事件投递分发、输入拦截注册、放大镜控制等所有核心逻辑。View / 窗口层View 树在无障碍事件触发时主动构造AccessibilityNodeInfo和AccessibilityEvent并通过AccessibilityManager跨进程提交给 AMS。ViewRootImpl同时实现了IAccessibilityInteractionConnection接口供 AccessibilityService 反向查询控件信息。输入系统层AMS 向 InputManagerService 注册AccessibilityInputFilter一个 InputFilter在输入事件到达 InputDispatcher 之前进行拦截。EventStreamTransformation链负责将原始输入事件转换为手势、触摸探索等语义事件。三、核心类关系一览3.1 服务管理链路AccessibilityService (应用进程) │ 通过 bindService 绑定 ▼ AccessibilityManagerService (system_server) ├── UserState (内部类, 按用户隔离的状态) │ ├── mEnabledServices: SetComponentName // 当前已启用的服务组件名 │ ├── mBindingServices: SetComponentName // 正在绑定中的服务 │ ├── mInstalledServices: ListAccessibilityServiceInfo // 已安装的服务 │ └── mBoundServices: CopyOnWriteArrayListService // 已绑定的 Service 实例 │ └── Service (内部类, extends IAccessibilityServiceConnection.Stub) ├── mServiceInterface: IAccessibilityServiceClient (回调接口) ├── mService: IBinder // 绑定的 Binder ├── mAccessibilityServiceInfo: AccessibilityServiceInfo ├── mId: int // 服务唯一 ID ├── mPendingEvents: SparseArrayAccessibilityEvent // 该服务待分发事件 └── mEventDispatchHandler: Handler // 事件分发 Handler源码路径frameworks/base/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.javaAMS 内部定义了两个关键内部类UserState负责按用户隔离无障碍状态启用的服务、已安装的服务等均在此处Service继承自IAccessibilityServiceConnection.Stub封装了一个已绑定的无障碍服务连接实例持有指向客户端进程的 Binder 回调接口IAccessibilityServiceClient字段名mServiceInterface。3.2 事件投递链路View (App 进程, UI 线程) │ sendAccessibilityEvent() ▼ AccessibilityManager (App 进程) │ sendAccessibilityEvent() → 通过 Handler 异步 │ → IAccessibilityManager.sendAccessibilityEvent() ▼ AccessibilityManagerService (system_server, 匿名 IAccessibilityManager.Stub) │ notifyAccessibilityServicesDelayedLocked() │ → 遍历各 Service, 放入 Service.mPendingEvents (SparseArray) │ → Service.mEventDispatchHandler 延迟处理 │ → notifyAccessibilityEventInternal() ▼ AccessibilityService (无障碍服务进程) │ IAccessibilityServiceClient.onAccessibilityEvent() ▼ onAccessibilityEvent(AccessibilityEvent)源码路径frameworks/base/core/java/android/view/View.javaframeworks/base/core/java/android/view/accessibility/AccessibilityManager.javaframeworks/base/core/java/android/accessibilityservice/AccessibilityService.javaframeworks/base/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java在 AMS 内部IAccessibilityManager.Stub的匿名实现是所有客户端调用进入 AMS 的入口点。事件到达后不会立即分发而是按服务放入各自的Service.mPendingEventsSparseArrayAccessibilityEvent由每个Service自己的mEventDispatchHandler延迟处理再调用notifyAccessibilityEventInternal()分发。这一设计避免了高频事件对系统的冲击。3.3 节点查询链路AccessibilityService (无障碍服务进程) │ event.getSource() / getRootInActiveWindow() ▼ AccessibilityInteractionClient (无障碍服务进程) │ findAccessibilityNodeInfoByAccessibilityId() │ → IAccessibilityInteractionConnection ▼ ViewRootImpl (App 进程, UI 线程) │ AccessibilityInteractionController │ → View.createAccessibilityNodeInfo() ▼ View.onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)源码路径frameworks/base/core/java/android/view/accessibility/AccessibilityInteractionClient.javaframeworks/base/core/java/android/view/ViewRootImpl.java这里有一个重要的设计细节AccessibilityInteractionClient是线程级单例但并非通过ThreadLocal实现而是用一个静态SparseArrayAccessibilityInteractionClient sClients以线程 id 为键来管理。源码注释明确指出“We do not have a thread local variable since other threads should be able to look up the correct client knowing a thread id”。这样设计是为了让其他线程能够通过线程 id 查到正确的客户端实例getInstanceForThread(threadId)而ThreadLocal做不到这一点。而ViewRootImpl内部的AccessibilityInteractionController则实现了IAccessibilityInteractionConnection.Stub负责处理来自 AccessibilityService 的节点查询 Binder 调用并将结果通过IAccessibilityInteractionConnectionCallback回调给请求方。3.4 输入拦截链路InputReader (native) │ InputEvent ▼ InputDispatcher (native) │ 在所有窗口派发前, 先经过 InputFilter ▼ AccessibilityInputFilter (system_server, 实现 IInputFilter) │ onInputEvent(InputEvent) │ → EventStreamTransformation 链 ▼ TouchExplorer (实现 EventStreamTransformation) │ onMotionEvent() │ → 手势识别 / 触摸探索 │ → 传递给下一个 Transformation 或 放行 ▼ MotionEventInjector (实现 EventStreamTransformation) │ → injectInputEvent() (虚拟点击注入)源码路径frameworks/base/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.javaframeworks/base/services/accessibility/java/com/android/server/accessibility/TouchExplorer.javaframeworks/base/services/accessibility/java/com/android/server/accessibility/EventStreamTransformation.javaframeworks/base/services/accessibility/java/com/android/server/accessibility/MotionEventInjector.javaAccessibilityInputFilter的注册发生在 AMS 的初始化过程中。当无障碍服务被启用且AccessibilityServiceInfo中声明了FLAG_REQUEST_TOUCH_EXPLORATION_MODE或FLAG_REQUEST_FILTER_KEY_EVENTS等标志时AMS 会调用InputManagerService.setInputFilter()将这个 InputFilter 注入到输入系统的处理链中。EventStreamTransformation是一个接口包级可见非 public定义了链式处理的契约源码路径frameworks/base/services/accessibility/java/com/android/server/accessibility/EventStreamTransformation.javainterfaceEventStreamTransformation{publicvoidonMotionEvent(MotionEventevent,MotionEventrawEvent,intpolicyFlags);publicvoidonKeyEvent(KeyEventevent,intpolicyFlags);publicvoidonAccessibilityEvent(AccessibilityEventevent);publicvoidsetNext(EventStreamTransformationnext);publicvoidclearEvents(intinputSource);publicvoidonDestroy();}关键设计接口里有 6 个方法注意clearEvents(int inputSource)是按输入源清理状态而非笼统的clear()此外还有一个onAccessibilityEvent()用于接收无障碍事件这是链中节点同步自身状态的途径。通过setNext()方法可以将多个 Transformation 串联成一个处理链AccessibilityInputFilter → TouchExplorer → KeyEventDispatcher → MotionEventInjector四、三条主干数据流整个无障碍服务模块可以归纳为三条核心数据流后续各篇也正是围绕这三条流程展开的4.1 事件流第四篇重点View.sendAccessibilityEvent() → AccessibilityManager.sendAccessibilityEvent() → (Binder) IAccessibilityManager.sendAccessibilityEvent() → AMS.notifyAccessibilityServicesDelayedLocked() → 遍历各 Service, 写入 Service.mPendingEvents (SparseArray) → Service.mEventDispatchHandler 延时处理 → Service.notifyAccessibilityEventInternal() → (Binder) IAccessibilityServiceClient.onAccessibilityEvent() → AccessibilityService.onAccessibilityEvent()方向View → AccessibilityManager → AMS → AccessibilityService单向推送4.2 节点流第五篇重点AccessibilityService.onAccessibilityEvent(event) → event.getSource() → AccessibilityInteractionClient.findAccessibilityNodeInfoByAccessibilityId() → (Binder) IAccessibilityInteractionConnection.findAccessibilityNodeInfoByAccessibilityId() → ViewRootImpl.AccessibilityInteractionController → View.createAccessibilityNodeInfo() → View.onInitializeAccessibilityNodeInfo() ← 返回 AccessibilityNodeInfo方向AccessibilityService → InteractionClient → ViewRootImpl → View请求-响应4.3 输入流第六、七篇重点InputReader → InputDispatcher → (InputFilter 拦截点) → AccessibilityInputFilter.onInputEvent() → TouchExplorer.onMotionEvent() → 手势识别 / 触摸探索处理 → 事件消费 or 放行 → 手势 → AMS.notifyGesture() → AccessibilityService.onGesture() → MotionEventInjector (虚拟点击) → InputManagerService.injectInputEvent() → InputDispatcher → 目标窗口方向输入系统 → AMS → AccessibilityService拦截 双向交互五、源码文件清单以下是无障碍服务模块涉及的核心源码文件按所在目录分类列出─────────────────────────────────────────────── 客户端层 (frameworks/base/core) ─────────────────────────────────────────────── frameworks/base/core/java/android/view/accessibility/ AccessibilityManager.java — 客户端事件发送、状态查询入口 AccessibilityEvent.java — 无障碍事件数据结构 AccessibilityNodeInfo.java — 无障碍节点信息数据结构 AccessibilityWindowInfo.java — 无障碍窗口信息数据结构 AccessibilityInteractionClient.java — 节点查询客户端按线程 id 管理的单例 AccessibilityRecord.java — AccessibilityEvent 的基类 AccessibilityCache.java — 客户端节点缓存 frameworks/base/core/java/android/accessibilityservice/ AccessibilityService.java — 无障碍服务基类 AccessibilityServiceInfo.java — 无障碍服务配置信息 frameworks/base/core/java/android/view/ View.java — View.sendAccessibilityEvent() / onInitializeAccessibilityNodeInfo() ViewGroup.java — ViewGroup.addChildrenForAccessibility() 子树遍历 ViewRootImpl.java — IAccessibilityInteractionConnection 实现 ─────────────────────────────────────────────── 服务端层 (frameworks/base/services) ─────────────────────────────────────────────── frameworks/base/services/java/com/android/server/ SystemServer.java — AMS 启动入口 frameworks/base/services/accessibility/java/com/android/server/accessibility/ AccessibilityManagerService.java — 核心总管服务含 Service、UserState 内部类 AccessibilityInputFilter.java — 输入事件过滤InputFilter TouchExplorer.java — 触摸探索处理器 EventStreamTransformation.java — 事件流变换链接口 KeyEventDispatcher.java — 按键事件分发器 MotionEventInjector.java — 模拟点击注入器 GestureUtils.java — 手势识别工具类 AccessibilityGestureDetector.java — 手势检测器 AutoclickController.java — 自动点击控制 KeyboardInterceptor.java — 键盘拦截器 MagnificationController.java — 放大镜控制器 MagnificationGestureHandler.java — 放大镜手势处理 DisplayAdjustmentUtils.java — 显示调整工具六、小结本文从宏观角度梳理了 AOSP 7 无障碍服务模块的整体架构。核心可以归纳为一个中枢、三条流、两个端点一个中枢AccessibilityManagerService运行在 system_server是全部无障碍逻辑的调度中心。三条流事件流View → AMS → Service、节点流Service → InteractionClient → View、输入流InputFilter → TouchExplorer → Service。两个端点View 层事件产生 节点构建和 AccessibilityService事件消费 节点查询 输入拦截。下一篇文章将深入AccessibilityManagerService的启动与初始化过程分析它在 SystemServer 中如何被创建、内部状态如何初始化以及如何监听系统配置变化。