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 Recientes.
Cuando una actividad pasaba a un estado detenido, el Administrador de ventanas no destruía las superficies de la actividad, siempre que esta estuviera en la parte superior de la tarea. Si se tuviera que volver a mostrar esta actividad, el Administrador de ventanas podría iniciar la animación sin esperar a que la actividad termine 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 unen con las instantáneas de tareas. Cuando una tarea pasa a segundo plano, Window Manager 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 se vuelva a mostrar la misma actividad, WindowManager creará una ventana de inicio (TaskSnapshotSurface) y adjuntará el GraphicBuffer sin copiar ninguna memoria en la cola de búfer de la ventana de inicio. En cuanto la actividad haya dibujado su primer fotograma, la ventana de inicio de la instantánea de tareas 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 que se use para dibujar el estado de vista previa de una tarea en la vista Recientes. Como solo es una referencia a un búfer, enviarlo a través de Binder consume pocos recursos. Cuando el GraphicBuffer llega a SystemUI, se une a un mapa de bits de hardware y, luego, se dibuja en la pantalla sin que se cargue memoria en la memoria gráfica.
Beneficios
Esta nueva arquitectura tiene tres beneficios principales:
- Si se usa la instantánea de la tarea como ventana de inicio, hay una buena transición 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 debía copiar en Ashmem y, luego, en la memoria gráfica. Dado que este método almacena la instantánea directamente en la memoria gráfica, no es necesario copiarla.
- El estado que ves en Recientes siempre coincide con el 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, Recientes ahora puede mostrar estas imágenes en resolución completa. Anteriormente, se bajaba la muestra en un 64% para ahorrar memoria.
Implementación
Esta función existe por completo en la plataforma de Android. No se requiere integración ni 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 esta función:
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 de 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 tarea desde el disco, primero se leen las instantáneas de baja resolución y, luego, se reemplazan por su contraparte 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 cuando se lee el archivo de instantánea del disco, y el usuario vería una tarjeta de tareas en blanco hasta que la imagen esté disponible. Puedes configurar las escalas en el archivo de configuración de superposición del dispositivooverlay/frameworks/base/core/res/res/values/config.xml
configurando config_highResTaskSnapshotScale
y config_lowResTaskSnapshotScale
. De forma predeterminada, se establecen en 1.0 y 0.5, respectivamente. Para inhabilitar las instantáneas de baja resolución, configura config_lowResTaskSnapshotScale
en 0.0.
Ejemplos y fuente
Busca el resto del código de esta función en los archivos TaskSnapshot* en:
frameworks/base/+/main/services/core/java/com/android/server/wm/