简析android系统长按后调出最近任务列表如何实现

462 阅读5分钟

首先,从 Android 系统架构来看,最近任务的管理和显示涉及多个模块:

1. 核心逻辑:SystemUI 与 ActivityManagerService(AMS)

  • ActivityManagerService(AMS) :系统服务,负责管理所有 Activity 的生命周期,包括记录最近运行的任务(通过ActivityStackTaskRecord维护任务栈)。
  • SystemUI:系统界面模块,其中的Recents 组件(位于SystemUI/src/com/android/systemui/recents)负责显示最近任务列表。但触发逻辑需要和 AMS 交互。

2. 触发方式:长按事件的监听

  • 物理 Home 键:早期设备通过长按 Home 键触发,监听逻辑在SystemUI 的 KeyEvent 处理中,或者由 Launcher 的 Home 键事件转发(但更核心的是系统级按键处理)。
  • 手势操作(如底部上滑):现代设备(尤其是全面屏)的手势触发,由SystemUI 的 NavigationBar 或手势导航模块处理,比如NavigationBarView监听触摸事件,判断长按或滑动手势。

3. 实现流程分解

步骤 1:事件监听

  • 物理按键:系统通过InputManagerService捕获按键事件,长按 Home 键的事件会被传递到SystemUI 的 Recents 组件,或者通过PhoneWindowManager处理(框架层)。
  • 手势:由SystemUI的手势导航逻辑(如GestureNavigationHelper)检测到长按或特定滑动手势(比如底部栏长按)。

步骤 2:获取最近任务数据

  • 当触发事件发生时,SystemUI 会调用AMS 的接口(如ActivityManager#getRecentTasks()),获取最近运行的任务列表(包含 Activity 的快照、标题、包名等信息)。

步骤 3:界面渲染

  • SystemUI 的RecentsActivity 或 RecentsFragment负责将任务数据渲染成 UI(比如卡片式布局),展示应用缩略图、标题等。这里的布局和动画由 SystemUI 实现,涉及自定义 View 和 RecyclerView 等组件。

步骤 4:交互处理

  • 用户操作(如滑动关闭、切换应用)会反馈给 AMS,调整任务栈状态,同时 SystemUI 更新界面。

4. Launcher vs SystemUI?

  • SystemUI 是核心:负责显示最近任务的 UI,以及处理触发事件(尤其是手势和系统按键)。
  • Launcher 角色次要:早期 Launcher 可能处理 Home 键的长按事件,但现代 Android 中,最近任务属于系统级功能,统一由 SystemUI 管理。Launcher 主要负责桌面、应用抽屉,而非系统级的任务切换界面。

5. 代码层面的关键模块(以 AOSP 为例)

  • SystemUI 模块

    • 路径:frameworks/base/packages/SystemUI/
    • 核心类:RecentsActivity(任务列表界面)、RecentsImpl(逻辑控制)、TaskStackView(任务卡片展示)。
  • AMS

    • 路径:frameworks/base/services/core/java/com/android/server/am/
    • 核心类:ActivityManagerService(提供任务数据)、TaskRecord(任务模型)。
  • 输入处理

    • PhoneWindowManager 处理物理按键事件,判断长按 Home 键后通知 SystemUI。
    • 手势处理由SystemUIGestureNavigation相关类实现(如EdgeGestureHandler)。

6. 厂商定制的差异

不同品牌(如三星、小米)可能会:

  • 自定义最近任务的 UI(如动画、布局),但核心逻辑仍基于 SystemUI。
  • 调整触发方式(如长按侧边栏、不同手势),但事件监听和数据获取仍依赖 AMS 和 SystemUI。

总结

  • 实现核心:由 SystemUI 负责界面显示和交互,通过 AMS 获取任务数据,事件触发可来自物理按键(Home 键长按)或手势(由 SystemUI 的导航模块处理)。

  • Launcher 不参与:Launcher 管理桌面,而最近任务是系统级功能,归 SystemUI 管辖。

简单来说,长按调出最近任务栏的流程是:SystemUI 监听长按事件 → 向 AMS 请求任务数据 → 渲染并显示任务列表

Android 系统中,长按触发 “最近任务栏(Recents Screen)”  的实现涉及 系统框架(SystemUI、AMS)  和 交互逻辑 ,核心流程如下:

一、核心模块分工

模块角色关键代码位置(AOSP)
SystemUI负责 显示最近任务的 UI、处理长按 / 手势事件,是交互的 “前端”frameworks/base/packages/SystemUI/recents
ActivityManagerService(AMS)系统服务,负责 管理任务栈(记录最近运行的应用),是数据的 “后端”frameworks/base/services/core/java/com/android/server/am/

二、实现流程拆解

1. 事件触发:长按 / 手势的监听

  • 物理 Home 键长按

    • 系统通过 InputManagerService 捕获按键事件,PhoneWindowManager 判断长按行为后,通过 Binder 通信 通知 SystemUI 启动最近任务界面。
  • 手势触发(如底部栏长按、全面屏手势):

    • 由 SystemUI 的导航模块(如 GestureNavigationHelperNavigationBarView)监听触摸事件,识别长按或特定滑动手势(如底部上滑停顿)。

2. 数据获取:从 AMS 拉取最近任务

SystemUI 触发后,通过 AMS 的接口(如 ActivityManager#getRecentTasks())获取任务数据:

  • 任务模型TaskRecord 包含应用快照(Thumbnail)、包名、Activity 状态等信息。
  • 数据过滤:AMS 会根据系统策略(如最近任务数量、隐私保护)筛选可显示的任务。

3. 界面渲染:SystemUI 绘制任务列表

SystemUI 的 RecentsActivity/RecentsFragment 负责渲染 UI:

  • 布局:通过 TaskStackView 以 “卡片式” 展示任务缩略图,支持滑动、删除等交互。
  • 动画:实现任务切换的过渡动画(如缩放、渐变),提升体验。

4. 交互反馈:更新任务状态

用户操作(如切换应用、滑动关闭)会通过 SystemUI 反馈给 AMS,由 AMS 调整任务栈的状态(如恢复前台 Activity、移除任务)。

三、Launcher 为何不参与?

Launcher(如 Pixel Launcher、第三方桌面)的职责是 管理桌面、应用抽屉,而 最近任务栏是系统级功能(属于系统界面),因此:

  • Launcher 不负责监听系统级长按事件(如 Home 键)。
  • 即使部分定制系统让 Launcher 处理桌面长按,系统级的最近任务仍由 SystemUI 独立实现

四、厂商定制的差异

不同品牌(如三星 OneUI、小米 MIUI)会在 SystemUI 层自定义

  1. UI 样式:修改任务卡片的布局、动画(如折叠效果、侧栏快捷操作)。
  2. 触发方式:调整长按逻辑(如长按侧边栏、不同手势),但核心仍依赖 SystemUI + AMS 的架构。

总结:为何是 SystemUI?

  • 系统级功能:最近任务栏属于系统界面(非第三方应用),由 SystemUI 统一管理。

  • 数据权限:AMS 的任务数据属于系统敏感信息,需 SystemUI(系统进程)调用。

  • 交互一致性:确保不同应用的任务切换体验统一,避免 Launcher 碎片化。

简言之,长按调出最近任务栏的核心是 SystemUI 监听事件 → 调用 AMS 获取数据 → 渲染 UI,Launcher 不参与这一系统级流程。