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 树在无障碍事件触发时主动构造 AccessibilityNodeInfo 和 AccessibilityEvent,并通过 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_MODE 或 FLAG_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 中如何被创建、内部状态如何初始化,以及如何监听系统配置变化。

相关推荐
千里马学框架4 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone4 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo4 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077004 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼4 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone4 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen4 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone4 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui