Exploración de los temas oscuros y claros de la interfaz de usuario del sistema y el proceso de reemplazo de fondos de pantalla
En la versión 9.0, Google agregó un modificador para esta función, que permite a los usuarios forzar el uso de colores de fondo del tema:
Sin más preámbulos, echemos un vistazo al código fuente completo. Todo el proceso según el fondo de pantalla.
Primero, presentemos brevemente cómo modificar el fondo de pantalla del sistema en Android. Si se trata de una aplicación de terceros, primero debe solicitar permisos del sistema:
Luego debe configurar. el fondo de pantalla estático a través de la interfaz relacionada con WallpaperManager.
WallpaperManager proporciona tres métodos: setBitmap(bitmap), setResource(resid) y setStream(inputstream) para configurar fondos de pantalla estáticos. A continuación se utiliza el código fuente de setBitmap como ejemplo.
A juzgar por el método anterior, hay una operación de escritura de archivos en el proceso de configuración del fondo de pantalla. Sabemos que el fondo de pantalla estático de SystemUI es ImageWallpaper, entonces, ¿cómo notifica el proceso anterior a ImageWallpaper?
WallpaperObserver hereda de FileObserver, y la clase FileObserver es un oyente que se utiliza para monitorear el acceso, creación, modificación, eliminación, movimiento y otras operaciones de archivos. Movimiento y otras operaciones. Puede escuchar un archivo o carpeta y volver a llamar al método onEvent() cuando ocurre la operación anterior.
Regrese al método setBitmap descrito anteriormente. El método setWallpaper() de WallpaperManagerService obtendrá un descriptor de archivo.
Luego observe la implementación de updateWallpaperBitmapLocked():
<. p> De la implementación anterior, podemos ver claramente que la ruta al archivo se usa como ruta al archivo, y la ruta al archivo se usa como ruta al archivo. De la implementación anterior, podemos ver que la ruta del archivo se obtiene mediante el método getWallpaperDir(). Entendiendo esto, podemos presentar fácilmente WallpaperObserver. En su constructor, la ruta obtenida mediante getWallpaperDir() se devuelve al constructor de la clase principal para que pueda comenzar a escuchar el evento CLOSE_WRITE del fondo de pantalla.Aquí está la implementación del método onEvent() para devoluciones de llamada:
notifyColorsQue es un valor int, inicialmente establecido en 0. Las actualizaciones del fondo de pantalla se producen cuando el nuevo archivo de fondo de pantalla obtenido a través de la ruta del fondo de pantalla no coincide con la variable global guardada previamente. notifyColorsQue realizará una operación OR bit a bit con FLAG_SYSTEM;
El método notifyWallpaperColorsChanged() pasará los parámetros al método notifyColorListeners() para su procesamiento, por lo que saltaremos directamente a la implementación de notifyColorListeners(): p>
El método notifyWallpaperColorsChanged() notificará a los oyentes de cambio de color del fondo de pantalla del sistema y de la pantalla de bloqueo. Solo analizaremos los procesos relacionados con el fondo de pantalla del sistema.
En este método, primero obtendrá una RemoteCallbackList del ID de usuario actual a través de mColorsChangedListeners. Esta clase es una clase contenedora a nivel de sistema. El objeto es una interfaz mCallbacks, que se utiliza para ejecutar la función de devolución de llamada en la lista de objetos. También hay varios métodos más importantes:
currentUserColorListeners de WallPaperObserver guarda algunos objetos IWallpaperManagerCallback, luego recorre todas las devoluciones de llamada a través de getBroadcastItem() y llama al mCallback de cada devolución de llamada. Luego, repita todas las devoluciones de llamada a través de getBroadcastItem() y llame a onWallpaperColorsChanged() para cada devolución de llamada.
Esto es lo que sucede en el método onStart() de StatusBar:
SysuiColorExtractor hereda de ColorExtractor, que a su vez implementa WallpaperManager.OnColorsChangedListener
En SysuiColorExtractor En SysuiColorExtractor, tenemos el método onWallpaperColorsChanged(), que implementa WallpaperManager.OnColorsChangedListener
En SysuiColorExtractor, tenemos el método onWallpaperColorsChanged(). p> En el constructor de SysuiColorExtractor, regístrese como OnColorsChangedListener a través del método addOnColorsChangedListener () de WallpaperManager y finalmente llame al método addOnColorsChangedListener () de WallpaperManager.sGlobals. Método addOnColorsChangedListener() de sGlobals:
Luego, registrará su propio IWallpaperManagerCallback y userId a través del método RegisterWallpaperColorsCallback() de WallpaperManagerService:
Este paso es similar al proceso de notificación de la sección anterior. En consecuencia, agregue un nuevo objeto RemoteCallbackList en mColorsChangedListeners y registre la devolución de llamada correspondiente para notificaciones posteriores (la devolución de llamada aquí es un objeto Globals).
Bien, después de completar el proceso de registro, finalmente echemos un vistazo a cómo responde SystemUI a los cambios en el color del fondo de pantalla.
Volviendo al final de la sección anterior, dijimos "recorrer getBroadcastItem() para encontrar todas las devoluciones de llamada y llamar a onWallpaperColorsChanged() de cada devolución de llamada respectivamente", y ya sabemos que la ubicación de esta devolución de llamada es WallpaperManager en el objeto de clase Globals, por lo que Encuentre su implementación:
Como se mencionó en la descripción anterior, la existencia del oyente es primero ColorExtractor, regrese a SystemUI,
recorra mOnColorsChangedListeners y llame a su método onColorsChanged(), en el Al comienzo de esta sección mencionamos que StatusBar se pasa como parámetro a ColorExtractor a través de addOnColorsChangedListener(). Luego agregue ColorExtractor a mOnColorsChangedListeners. El proceso es muy simple y no entraré en detalles aquí. Luego, llame a onColorsChanged() de StatusBar:
Finalmente, modifique los temas oscuros y claros relacionados con SystemUI en el método updateTheme().
Lo anterior es todo el proceso de registro y respuesta. En cuanto a cómo modificar los temas de estos controles en updateTheme () después de SystemUI, continuaremos estudiándolo en profundidad en el futuro.