Instantáneas de tareas es una infraestructura que se introdujo en Android 8.0 y que combina capturas de pantalla de miniaturas de Recientes y superficies guardadas del administrador de ventanas. Las miniaturas de Recientes representan el último estado de una tarea en la vista de Recientes.
Cuando una actividad pasaba a un estado detenido, el administrador de ventanas no destruía las superficies de la actividad mientras esta se encontrara en la parte superior de la tarea. Si esta actividad se tuviera que mostrar de nuevo, Window Manager podría iniciar la animación sin esperar a que la actividad terminara de dibujar su primer fotograma, ya que podría usar esta superficie guardada.
Arquitectura
Los dos conceptos de miniaturas de Recents y superficies guardadas se unifican con las instantáneas de tareas. Cuando una tarea pasa a segundo plano, WindowManager coloca una captura de pantalla de esta tarea en un GraphicBuffer. Mientras la app de la actividad superior de la tarea permanezca en la memoria, este GraphicBuffer se retendrá en la memoria. Ahora, cuando la misma actividad se vuelve a traer al frente, WindowManager creará una ventana de inicio (TaskSnapshotSurface) y adjuntará el GraphicBuffer sin copiar memoria en la cola de búfer de la ventana de inicio. En cuanto la actividad dibuje su primer fotograma, la ventana de inicio de la instantánea de la tarea se desvanecerá suavemente como las pantallas de presentación normales.
El mismo GraphicBuffer también se envía a través de Binder a SystemUI para dibujar el estado de vista previa de una tarea en la vista de Recientes. Dado que solo es una referencia a un búfer, enviarlo a través de Binder requiere pocos recursos. Cuando el GraphicBuffer llega a SystemUI, se encapsula en un mapa de bits de hardware y, luego, se dibuja en la pantalla sin que se suba memoria a la memoria de gráficos.
Beneficios
Esta nueva arquitectura ofrece tres beneficios principales:
- Si la instantánea de la tarea se usa como ventana inicial, se produce una transición cruzada agradable entre la instantánea y el contenido real.
- Cuando se dibuja la instantánea de la tarea en SystemUI, se puede hacer sin ninguna copia. Anteriormente, el mapa de bits se tenía que copiar en Ashmem y, luego, en la memoria de gráficos. Dado que este método almacena la instantánea directamente en la memoria de gráficos, no es necesario copiarla.
- El estado que ves en Recientes siempre coincide con el estado que verás por primera vez cuando vuelvas a abrir la app. Tener el mismo búfer aquí también ahorra mucha memoria. Por eso, la función Recientes ahora puede mostrar estas imágenes en resolución completa. Anteriormente, se reducía la muestra en un 64% para ahorrar memoria.
Implementación
Esta función existe completamente en la plataforma de Android. No se requiere integración y no se admite la personalización. Sin embargo, los fabricantes de dispositivos pueden inhabilitar por completo la función de Instantáneas de tareas.
Para inhabilitar esta función, modifica lo siguiente:
frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java#215
Ten en cuenta que, si la función está inhabilitada, la vista Recientes no mostrará ninguna miniatura.
Instantáneas en alta y baja resolución
Las instantáneas de tareas se escriben en el disco en dos escalas. Cuando se restablece una instantánea de la tarea desde el disco, primero se leen las instantáneas de baja resolución y, luego, se reemplazan por sus equivalentes de alta resolución. Esta optimización mejora los tiempos de carga de las imágenes. De lo contrario, podría haber una ligera demora al leer el archivo de instantánea del disco, y el usuario vería una tarjeta de tarea en blanco hasta que la imagen estuviera disponible. Puedes configurar las escalas en el archivo de configuración de superposición del dispositivooverlay/frameworks/base/core/res/res/values/config.xml estableciendo config_highResTaskSnapshotScale y config_lowResTaskSnapshotScale. De forma predeterminada, estos valores se establecen en 1.0 y 0.5, respectivamente. Para inhabilitar las instantáneas de baja resolución, establece config_lowResTaskSnapshotScale en 0.0.
Ejemplos y fuente
Encontrarás el resto del código de esta función en los archivos TaskSnapshot* en:
frameworks/base/+/android17-release/services/core/java/com/android/server/wm/