Android 7系统无障碍服务(一)全景图与架构概览

系列目录第一篇:全景图与架构概览 | [第二篇:AccessibilityManagerService 启动与初始化](#第二篇:AccessibilityManagerService 启动与初始化) | 第三篇:无障碍服务的注册与绑定 | [第四篇:AccessibilityEvent 的产生与投递](#第四篇:AccessibilityEvent 的产生与投递) | [第五篇:AccessibilityNodeInfo 的构建与查询](#第五篇:AccessibilityNodeInfo 的构建与查询) | [第六篇:输入事件拦截与 TouchExplorer](#第六篇:输入事件拦截与 TouchExplorer) | [第七篇:手势分发与 KeyEvent 处理](#第七篇:手势分发与 KeyEvent 处理) | 第八篇:放大镜与辅助功能特性


一、无障碍服务是什么

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     │
└──────────────────┘

架构分为五层:

  1. 应用层 :开发者继承 AccessibilityService,在 Manifest 中通过 BIND_ACCESSIBILITY_SERVICE 权限和 android.accessibilityservice 的 intent-filter 声明,由系统进程完成绑定和生命周期管理。

  2. Framework 客户端层 :运行在普通 App 进程(或 AccessibilityService 进程)中,提供两个核心客户端入口------AccessibilityManager 负责事件的发送和全局状态的查询,AccessibilityInteractionClient 负责对控件树的跨进程查询。

  3. Framework 服务端层 :以 AccessibilityManagerService 为中心,运行在 system_server 进程中。它是整个无障碍功能的中枢,负责服务绑定管理、事件投递分发、输入拦截注册、放大镜控制等所有核心逻辑。

  4. View / 窗口层 :View 树在无障碍事件触发时主动构造 AccessibilityNodeInfoAccessibilityEvent,并通过 AccessibilityManager 跨进程提交给 AMS。ViewRootImpl 同时实现了 IAccessibilityInteractionConnection 接口,供 AccessibilityService 反向查询控件信息。

  5. 输入系统层 :AMS 向 InputManagerService 注册 AccessibilityInputFilter(一个 InputFilter),在输入事件到达 InputDispatcher 之前进行拦截。EventStreamTransformation 链负责将原始输入事件转换为手势、触摸探索等语义事件。


三、核心类关系一览

3.1 服务管理链路

复制代码
AccessibilityService (应用进程)
    │ 通过 bindService 绑定
    ▼
AccessibilityManagerService (system_server)
    ├── Service (内部类, 代表一个已绑定的 AccessibilityService)
    │     ├── mService: IAccessibilityServiceClient (回调接口)
    │     ├── mServiceInfo: AccessibilityServiceInfo
    │     └── mId: 服务唯一 ID
    ├── mEnabledServices: List<Service>  // 当前已启用的服务
    ├── mBindingServices: Set<ComponentName>  // 正在绑定中的服务
    └── mInstalledServices: List<AccessibilityServiceInfo>  // 已安装的服务

源码路径frameworks/base/services/core/java/com/android/server/accessibility/AccessibilityManagerService.java

AMS 内部定义了一个名为 Service 的内部类(部分 Android 版本中也叫 AccessibilityServiceConnection),它封装了一个已绑定的无障碍服务连接实例,持有指向客户端进程的 Binder 回调接口 IAccessibilityServiceClient

3.2 事件投递链路

复制代码
View (App 进程, UI 线程)
    │ sendAccessibilityEvent()
    ▼
AccessibilityManager (App 进程)
    │ sendAccessibilityEvent() → 通过 Handler 异步
    │ → IAccessibilityManager.sendAccessibilityEvent()
    ▼
AccessibilityManagerService.mService (system_server, 匿名 Binder)
    │ notifyAccessibilityServicesDelayedLocked()
    │ → 放入 mPendingEvents 队列
    │ → mMainHandler 延迟处理
    │ → 遍历 mEnabledServices
    ▼
AccessibilityService (无障碍服务进程)
    │ IAccessibilityServiceClient.onAccessibilityEvent()
    ▼
    onAccessibilityEvent(AccessibilityEvent)

源码路径

  • frameworks/base/core/java/android/view/View.java
  • frameworks/base/core/java/android/view/accessibility/AccessibilityManager.java
  • frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java

在 AMS 内部,mService 是一个匿名 IAccessibilityManager.Stub 实现,它是所有客户端调用进入 AMS 的入口点。事件到达后不会立即分发,而是放入 mPendingEvents 队列并交由 mMainHandler 延迟处理,这一设计避免了高频事件对系统的冲击。

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.java
  • frameworks/base/core/java/android/view/ViewRootImpl.java

这里有一个重要的设计细节:AccessibilityInteractionClient 是线程级单例(通过 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/core/java/com/android/server/accessibility/AccessibilityInputFilter.java
  • frameworks/base/services/core/java/com/android/server/accessibility/TouchExplorer.java
  • frameworks/base/services/core/java/com/android/server/accessibility/EventStreamTransformation.java
  • frameworks/base/services/core/java/com/android/server/accessibility/MotionEventInjector.java

AccessibilityInputFilter 的注册发生在 AMS 的初始化过程中。当无障碍服务被启用且 AccessibilityServiceInfo 中声明了 FLAG_REQUEST_TOUCH_EXPLORATION_MODEFLAG_REQUEST_FILTER_KEY_EVENTS 等标志时,AMS 会调用 InputManagerService.setInputFilter() 将这个 InputFilter 注入到输入系统的处理链中。

EventStreamTransformation 是一个接口,定义了链式处理的契约:

java 复制代码
// 源码路径:frameworks/base/services/core/java/com/android/server/accessibility/EventStreamTransformation.java

public interface EventStreamTransformation {
    void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags);
    void onKeyEvent(KeyEvent event, int policyFlags);
    void setNext(EventStreamTransformation next);
    void clear();
    void onDestroy();
}

通过 setNext() 方法,可以将多个 Transformation 串联成一个处理链:

AccessibilityInputFilter → TouchExplorer → KeyEventDispatcher → MotionEventInjector


四、三条主干数据流

整个无障碍服务模块可以归纳为三条核心数据流,后续各篇也正是围绕这三条流程展开的:

4.1 事件流(第四篇重点)

复制代码
View.sendAccessibilityEvent()
    → AccessibilityManager.sendAccessibilityEvent()
        → (Binder) IAccessibilityManager.sendAccessibilityEvent()
            → AMS.notifyAccessibilityServicesDelayedLocked()
                → mPendingEvents 队列
                → mMainHandler 延时处理
                → notifyClearAccessibilityCacheLocked()
                → 遍历 mEnabledServices
                → (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    --- 节点查询客户端(线程单例)
    AccessibilityRecord.java               --- AccessibilityEvent 的基类

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/core/java/com/android/server/accessibility/
    AccessibilityManagerService.java      --- 核心总管服务
    AccessibilityInputFilter.java         --- 输入事件过滤(InputFilter)
    TouchExplorer.java                    --- 触摸探索处理器
    EventStreamTransformation.java        --- 事件流变换链接口
    KeyEventDispatcher.java               --- 按键事件分发器
    MotionEventInjector.java              --- 模拟点击注入器
    GestureUtils.java                     --- 手势识别工具类
    ScreenMagnifier.java                  --- 全屏放大镜
    DisplayMagnifier.java                 --- 区域放大镜
    MagnificationController.java          --- 放大镜控制器

六、小结

本文从宏观角度梳理了 AOSP 7 无障碍服务模块的整体架构。核心可以归纳为"一个中枢、三条流、两个端点":

  • 一个中枢AccessibilityManagerService,运行在 system_server,是全部无障碍逻辑的调度中心。
  • 三条流:事件流(View → AMS → Service)、节点流(Service → InteractionClient → View)、输入流(InputFilter → TouchExplorer → Service)。
  • 两个端点:View 层(事件产生 & 节点构建)和 AccessibilityService(事件消费 & 节点查询 & 输入拦截)。

下一篇文章将深入 AccessibilityManagerService 的启动与初始化过程,分析它在 SystemServer 中如何被创建、内部状态如何初始化,以及如何监听系统配置变化。

相关推荐
Android-Flutter1 小时前
android 自定义view 详解
android·kotlin
WAsbry2 小时前
协程任务的失败控制:取消、异常传播与Supervisor
android
Android打工仔2 小时前
从 finally 理解程序的控制流:它为什么不是 catch 后面的代码?
android·kotlin
随遇丿而安2 小时前
第15周:Service 全功能 + 后台优化
android
YXL1111YXL2 小时前
续体和状态机 —— suspend 函数的 CPS 变换
android·kotlin
WAsbry2 小时前
Flow数据模型:冷流、状态、事件与共享策略
android
WAsbry2 小时前
深入理解 Kotlin suspend:挂起语义、状态机与恢复调度
android
WAsbry2 小时前
Flow在Android中的完整落地:异常、重试与生命周期
android
WAsbry2 小时前
协程共享状态:Atomic、Mutex、Semaphore与状态封闭
android