自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
任务快照
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
任务快照是在 Android 8.0 中引入的基础架构,可将窗口管理器中的最近任务缩略图和已保存表面这两者的屏幕截图进行合并。最近任务缩略图会在“最近”视图中呈现任务的最后状态。
过去,当有 activity 进入停止状态时,只要该 activity 位于任务顶层,窗口管理器就不会销毁该 activity 的 Surface。如果该 activity 必须再次显示,窗口管理器便能够启动相应动画,而无需等待该 activity 绘制完其第一帧,因为它能够使用这个已保存 Surface。
架构
通过任务快照,最近任务缩略图和已保存表面这两个概念合并在了一起。当有任务进入后台时,窗口管理器会将该任务的屏幕截图放入一个图形缓冲区中。只要任务顶层 activity 的应用保留在内存中,该图形缓冲区就会保留在内存中。现在,当同一个 activity 再次回到前面时,窗口管理器将会创建一个起始窗口 (TaskSnapshotSurface) 并附加图形缓冲区,而无需将任何内存复制到起始窗口的缓冲区队列。一旦该 Activity 绘制了其第一帧,任务快照起始窗口就会立即像常规启动画面一样平滑淡出。
系统还会将同一个图形缓冲区通过 Binder 发送到 SystemUI,以用于在“最近”视图中绘制任务的预览状态。由于这只是对缓冲区的引用,因此通过 Binder 发送它只需要多占用很少的资源。当该图形缓冲区到达 SystemUI 时,将会被封装到硬件位图中,然后被绘制到屏幕上,而无需将任何内存上传到显存。
优势
这种新架构有以下三个主要优点:
- 如果将任务快照用作起始窗口,快照和实际内容之间会有一个很好的交叉淡入淡出过程。
- 在 SystemUI 中绘制任务快照时,无需进行任何复制操作即可完成。以前则必须将位图复制到 Ashmem 中,然后再复制到图形内存。由于这种方法是将快照直接存储在显存中,因此无需进行任何复制操作。
- 您在“最近”视图中看到的状态始终会与您在重新打开应用时首先看到的状态一致。拥有相同的缓冲区还能够节省大量内存。这就是“最近”视图现在能够以完整分辨率显示这些图像的原因。以前,系统会将采样减少 64% 以节省内存。
实现
该功能完全位于 Android 平台中。无需集成,也不支持自定义。不过,设备制造商可以完全停用任务快照功能。
如需停用该功能,请修改以下函数:
frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java#215
请注意,如果该功能被停用,“最近”视图将不会显示任何缩略图。
高分辨率快照和低分辨率快照
任务快照以两种比例写入磁盘。从磁盘恢复任务快照时,会先读取低分辨率快照,然后将其替换为对应的高分辨率快照。这项优化可缩短映像加载时间。否则,从磁盘读取快照文件时可能会有轻微的延迟,并且在映像可用之前,用户将看到一张空白任务卡。您可以通过设置
config_highResTaskSnapshotScale
和
config_lowResTaskSnapshotScale
,在设备叠加层配置文件
overlay/frameworks/base/core/res/res/values/config.xml
中配置比例。默认情况下,这两个值分别设置为 1.0 和 0.5。将
config_lowResTaskSnapshotScale
设置为 0.0 可停用低分辨率快照。
示例和源代码
您可以在位于以下位置的 TaskSnapshot* 文件中找到该功能的其余代码:
frameworks/base/+/main/services/core/java/com/android/server/wm/
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-03-26。
[null,null,["最后更新时间 (UTC):2025-03-26。"],[],[],null,["# Task snapshots\n\n*Task Snapshots* is infrastructure introduced in Android 8.0 that combines\nscreenshots for *Recents Thumbnails* as well as *Saved Surfaces*\nfrom Window Manager. Recents Thumbnails represent the last state of a task in\nthe Recents view.\n\n\nWhen an activity went into a stopped state, Window Manager didn't destroy the\nsurfaces of the activity as long as that activity was on the top of the task. If\nthis activity had to be shown again, Window Manager was able to start the\nanimation without waiting for the activity to finish drawing its first frame, as\nit was able to use this Saved Surface.\n\nArchitecture\n------------\n\n\nThe two concepts of Recents Thumbnails and Saved Surfaces are unified with Task\nSnapshots. When a task goes into background, Window Manager places a screenshot\nof this task into a GraphicBuffer. As long as the app of the top\nactivity of the task stays in memory, this GraphicBuffer will be retained in\nmemory. Now, when the same activity is brought to the front again, Window\nManager will create a starting window (TaskSnapshotSurface), and attach the\nGraphicBuffer without copying any memory to the buffer queue of the starting\nwindow. As soon as the activity has drawn its first frame, the Task Snapshot\nstarting window will fade out smoothly like regular splash screens.\n\n\nThe same GraphicBuffer is also sent over Binder to SystemUI to be used to draw\nthe preview state of a task in the Recents view. Since this is just a reference\nto a buffer, sending it over binder expends few resources. When the\nGraphicBuffer arrives at SystemUI, it is wrapped into a hardware Bitmap and then\ndrawn onto the screen without any memory uploading to the graphics memory.\n\nBenefits\n--------\n\n\nThere are three main benefits to this new architecture:\n\n- If the task snapshot is used as a starting window, there is a nice crossfade between the snapshot and the real content.\n- When the task snapshot is drawn in SystemUI, it can be done so without any copying. Previously the bitmap had to be copied into Ashmem, then into graphics memory. Since this method stores the snapshot directly in graphics memory, no copying is needed.\n- The state you see in Recents always matches the state you'll first see when reopening the app. Having the same buffer here also saves a lot of memory. That's why Recents is now able to show these images at full resolution. Previously, it was down sampled by 64% to save memory.\n\nImplementation\n--------------\n\n\nThis feature exists entirely in the Android platform. No integration is\nrequired, and customization isn't supported. However, device manufacturers can\ndisable the Task Snapshots feature entirely.\n\n\nTo disable this feature, modify this function: \n\n```text\nframeworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java#215\n```\n\n\nNote that if the feature is disabled, the Recents view will not show any\nthumbnails whatsoever.\n\nHigh-res and low-res snapshots\n------------------------------\n\nTask snapshots are written to the disk at two scales. When restoring a task snapshot from the disk, low-res snapshots are read first, and then replaced by their high-res counterpart. This optimization improves image load times. Otherwise, there could be a slight delay when reading the snapshot file from the disk, and the user would see a blank task card until the image was available. You can configure the scales in the device overlay config file `overlay/frameworks/base/core/res/res/values/config.xml` by setting `config_highResTaskSnapshotScale` and `config_lowResTaskSnapshotScale`. By default, these are set to 1.0 and 0.5 respectively. Disable low-res snapshots by setting `config_lowResTaskSnapshotScale` to 0.0.\n\nExamples and source\n-------------------\n\n\nFind the rest of the code for this feature within the TaskSnapshot\\* files in: \n\n```text\nframeworks/base/+/android16-release/services/core/java/com/android/server/wm/\n```"]]