Binders en Android (Parte II): Recuento de referencias y destinatarios de defunciones | de Ashu Tyagi | Noviembre de 2020

Foto de Crissy Jarvis en Unsplash

Esta es la segunda parte de una serie de varias partes sobre carpetas en Android. Es muy recomendable que lea la Parte I (si aún no lo ha hecho); de lo contrario, esta parte probablemente no tendrá mucho sentido.

Otros artículos de esta serie:

En la primera parte vimos que la carpeta se usa para todo esto pasa a través de los procesos en la plataforma principal. Son la fuerza impulsora detrás de la interacción en el marco y se utilizan ampliamente en el sistema de seguridad. En esta parte hablaremos de algunas características muy importantes de los aglutinantes que lo hacen adecuado para entornos hostiles. Pero, ¿por qué también necesitamos conocer los destinatarios de la muerte y el mecanismo de recuento de referencias?

Desde el principio, el enfoque central de Android ha sido la capacidad de realizar múltiples tareas. Para lograr esto, Android adopta un enfoque único al permitir que varias aplicaciones se ejecuten simultáneamente. Los usuarios generalmente nunca cierran aplicaciones explícitamente, sino que las dejan ejecutándose en segundo plano. Cuando queda poca memoria, el sistema Android elimina las aplicaciones de baja prioridad que están presentes en segundo plano. Esta capacidad de mantener los procesos en espera en segundo plano acelera el cambio de aplicación en un momento posterior.

Android no depende de que las aplicaciones estén bien escritas y respondan a las solicitudes de salida educadas. Más bien, los mata brutalmente por la fuerza sin previo aviso, lo que permite que el kernel recupere inmediatamente los recursos asociados con el proceso. Esto ayuda a prevenir situaciones graves de poca memoria y le da a Android un control total sobre las aplicaciones que se comportan mal y que tienen un impacto negativo en el sistema. Por esta razón, no hay garantía de que cualquier código de espacio de usuario (como una Actividad onDestroy() método) nunca se ejecutará cuando se detenga un proceso de aplicación.

Teniendo en cuenta la memoria limitada disponible en entornos móviles, este enfoque parece prometedor. Sin embargo, todavía hay un problema que debe abordarse: ¿Cómo debe el sistema detectar la muerte de una aplicación para que pueda limpiar rápidamente su estado?? Cuando una aplicación muere, su estado se distribuirá entre docenas de servicios del sistema (Administrador de actividades, Administrador de ventanas, Administrador de energía, etc.) y varios procesos. Estos servicios del sistema deben ser notificados de inmediato cuando una aplicación muere para que puedan limpiar su estado y mantener una instantánea precisa del sistema. Aquí entra el destinatario de la muerte y el recuento de referencias. Ahora tenemos buenas razones para aprender sobre estas características, así que veámoslo.

Referencia contar asegura que los objetos de Binder se liberen automáticamente cuando nadie hace referencia a ellos y se implementa en el controlador del kernel. El controlador del kernel de binder no sabe nada sobre los objetos de binder que se han compartido con un proceso remoto, en cambio, lo que realmente sucede es:

  1. Una vez que se encuentra una nueva referencia al objeto binder en una transacción, el controlador del kernel del binder la recuerda.
  2. Cada vez que la referencia se comparte con otro proceso, se incrementa el recuento de referencias.
  3. El recuento de referencias se reduce de forma explícita o automática cuando el proceso muere.
  4. Cuando una referencia ya no es necesaria, se informa a su propietario que se puede liberar y el recopilador elimina su asignación.

La función de “enlace a la muerte” de Binder permite que un proceso reciba una devolución de llamada cuando se aborta otro proceso que aloja un objeto de Binder. En Android, cualquier proceso puede ser notificado cuando otro proceso muere haciendo lo siguiente:

  1. Primero, el proceso crea un archivo DeathRecipient objeto de devolución de llamada que contiene el código que se ejecutará al llegar la notificación de muerte.
  2. A continuación, obtiene una referencia a un archivo. Binder objeto que vive en otro proceso y llama a su propio linkToDeath(IBinder.DeathRecipient recipient, int flags), pasando el DeathRecipient objeto de devolución de llamada como primer argumento.
  3. Finalmente, espera el proceso que aloja el archivo. Binder Objeto a morir. Cuando el controlador del kernel de Binder detecta que el proceso que aloja el Binder se ha ido, alertará a los registrados DeathRecipient objeto de devolución de llamada llamando a su binderDied() método.

Mirando el archivo Código fuente de LocationManagerService nos ayuda a comprender lo que está sucediendo bajo el capó (tenga en cuenta que parte del código fuente se ha limpiado en aras de la brevedad):

  • Cuando la aplicación solicita obtener la ubicación, el servicio de administración de ubicación requestLocationUpdates() se llama al método. El servicio de administración de ubicación registra el oyente de ubicación para la aplicación y también se conecta a la muerte del oyente de ubicación único. Binder token para que pueda ser notificado si el proceso de solicitud aborta abruptamente.
  • Cuando la aplicación le solicita que elimine las actualizaciones de ubicación, el servicio de administración de ubicación removeUpdates() se llama al método. El servicio de gestión de la ubicación elimina el oyente de la aplicación y también se desconecta cuando el oyente único del oyente de la ubicación muere. Binder token (ya que ya no le importa que se le notifique cuando finalice el proceso de solicitud).
  • Cuando la aplicación finaliza abruptamente antes de que se elimine explícitamente el detector de ubicación, el controlador del kernel de Binder advierte que el token de Binder del detector de ubicación se ha adjuntado al final del proceso de aplicación. El controlador del kernel de Binder envía rápidamente una notificación de muerte al destinatario de muerte registrado binderDied() , que elimina rápidamente el detector de ubicación y actualiza el servicio de ubicación del dispositivo.

Las funciones de enlace de muerte y recuento de referencias de Binder son increíblemente útiles y los servicios del sistema del marco las utilizan ampliamente. Muchos otros servicios del sistema dependen de estas estructuras para garantizar que no se pierdan recursos costosos cuando un proceso de solicitud se interrumpe por la fuerza. Algunos otros ejemplos son VibratorService, PowerManagerService, GpsLocationProvider, y el WifiService.

If you like this article don't forget to clap and share!!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *