Hablando de la comunicación entre procesos de Android

Caso: /Usuarios/lucas/AndroidStudioProjects/aidldemo-master

Uno: sistema operativo

Desde la perspectiva de los principios del sistema operativo, existen tres métodos principales de comunicación de procesos: almacenamiento compartido, paso de mensajes y comunicación de canalización.

Dos: IPC en Android

Varias formas de comunicación entre procesos: Intent (Bundle), intercambio de archivos, Messenger, AIDL, ContentProvider, Socket, etc.

  • Bundle implementa la interfaz Parcelable
    • Ventajas: Facilidad de uso
    • Desventaja: solo se pueden pasar los tipos de datos admitidos por Bundle
    • Escenario de uso: comunicación de proceso entre los cuatro componentes principales
  • Compartición de archivos
    • Ventajas: Facilidad de uso
    • Desventajas: no es adecuado para escenarios de alta concurrencia y no puede lograr una comunicación instantánea
    • Escenarios de uso: escenarios sin acceso concurrente, intercambio simple de datos, bajos requisitos de tiempo real
  • AIDL
    • Ventajas: potente, admite comunicación concurrente de uno a muchos, admite comunicación en tiempo real
    • Desventajas: debe lidiar con el problema de la sincronización de subprocesos
    • Escenario de uso: Comunicación de uno a muchos, con el requisito de RPC (Protocolo de llamada a procedimiento remoto)
  • Mensaje
    • Ventajas: función general, admite comunicación en serie de uno a muchos, admite comunicación en tiempo real
    • Desventajas: no se pueden manejar mejor los escenarios de alta simultaneidad, no es compatible con RPC y los datos se transmiten a través de Message, por lo que solo puede admitir tipos de datos compatibles con Bundle
    • Escenario de uso: comunicación en tiempo real uno a muchos de baja simultaneidad, sin requisitos de RPC o RPC que no devuelven resultados
  • Proveedor de contenido
    • Ventajas: se utiliza principalmente para el acceso a datos, admite el intercambio de datos simultáneos de uno a muchos
    • Desventajas: Restringido, la fuente de datos del destacamento principal ha sido eliminada, modificada y verificada
    • Escenario de uso: uso compartido de datos de uno a muchos
  • Enchufe
    • Ventajas: función potente, transmisión de flujo de bytes a través de la red de lectura y escritura, admite comunicación paralela en tiempo real de uno a muchos
    • Desventaja: no admite RPC directo
    • Escenario de uso: Intercambio de datos Vioxx
  • Receptor de radiodifusión
    • Ventajas: operación simple, soporte de comunicación en tiempo real de uno a muchos
    • Desventajas: solo admite transmisión de datos unidireccional, baja eficiencia y baja seguridad
    • Escenario de uso: comunicación unidireccional de baja frecuencia de uno a muchos

Hay dos razones por las que Android elige Binder

  • Seguridad, el sistema Android le asignará UID y PID a cada proceso, no desea agregar tradicionalmente UID a los datos, lo que hace imposible que esos procesos maliciosos se comuniquen directamente con otros procesos, y se mejora la seguridad de la comunicación entre procesos
  • Eficiente, IPC como Socket necesita 2 veces para cada copia de datos, mientras que Binder solo necesita una vez, lo cual es muy importante en el caso de recursos limitados en teléfonos móviles.

2.1 AIDL

AIDLEs una forma Androidde implementar la comunicación entre procesos ( ). El mecanismo de transmisión de datos del sistema se basa en la limitación del tamaño de los datos de transmisión, y se informará una excepción si la transmisión supera 1 M de archivos (Nota 1). Una solución es usar memoria compartida anónima para la transmisión de archivos grandes .Inter-Process CommunicationAIDLBinderBinderandroid.os.TransactionTooLargeException

2.1: Introducción a la memoria compartida

La memoria compartida es una forma de comunicación entre procesos. El propósito de la memoria compartida se logra asignando una parte de la memoria pública a sus respectivos espacios de proceso.

shmem.png

Para escenarios donde se necesita transferir una gran cantidad de datos entre procesos, este método de comunicación es muy eficiente, pero la memoria compartida no proporciona un mecanismo de sincronización. Cuando un proceso escribe en la memoria compartida, no hay un mecanismo automático para evitar que el segundo proceso comience a leerlo. Por lo tanto, necesitamos un mecanismo de semáforo similar para sincronizar el acceso a la memoria compartida.

AndroidLa memoria compartida anónima (Ashmem) en está basada en Linuxmemoria compartida, y la transferencia de memoria compartida se realiza mediante Binder+ descriptor de archivo ( ). FileDescriptorPermite que varios procesos operen en la misma área de memoria y no existen otras restricciones de tamaño, excepto las restricciones de memoria física. En comparación con Linuxla memoria compartida, Ashmem administra la memoria con mayor precisión y agrega mutex. JavaLa capa debe usarse cuando se usa MemoryFiley encapsula nativeel código. AndroidLa práctica común de compartir memoria en la plataforma es la siguiente:

  • El proceso A MemoryFileobtiene fd( FileDescriptor) al crear memoria compartida
  • El proceso A escribe datos en la memoria compartida a través de fd
  • El proceso A encapsula fd en un objeto Parcelableque implementa la interfaz ParcelFileDescriptory Binderenvía ParcelFileDescriptorel objeto al proceso B mediante
  • El proceso B obtiene ParcelFileDescriptorfd del objeto y lee datos de fd

2.2: Cómo usar AIDL

Servidor: 1. Crear interfaz, 2. Definir carpeta, implementar interfaz, 3. Crear servicio, devolver carpeta;

Cliente: 1. Servicio de enlace, 2. Realice el monitoreo de enlace de ServiceConnection, 3. En la devolución de llamada de enlace exitoso, convierta IBinder en un objeto proxy de interfaz AIDL.

Una vez que el cliente y el servidor se vinculan con éxito, se puede llamar al objeto proxy a través de la interfaz de AIDL, al igual que llamar directamente al método local y llamar al método del servidor. Cabe señalar que los objetos que se pasan entre AIDL deben implementar la interfaz Parcelable.

2.3: Devolución de llamada de AIDL

Principio: es lo mismo que la interfaz de devolución de llamada de uso común, excepto que la devolución de llamada de aidl está en dos procesos.

Servidor: ITaskBinder.Stub() + interfaz de devolución de llamada

Cliente: defina una implementación concreta de devolución de llamada, tome el servicio del servidor, registre la devolución de llamada en él, luego servidor ITaskBinder.Stub() -> callback.xx() en él, luego llame a la implementación de devolución de llamada definida por el cliente

En el archivo aidl, la modificación unidireccional se usa para declarar el método como asíncrono

2.4: La capa inferior de AIDL: aglutinante

La relación entre los dos:

La interfaz definida por AIDL, además de ser una interfaz, también es un objeto Binder, que admite la conversión entre la interfaz y Binder (asBinder(), asInterface()). Después de crear la interfaz AIDL, el sistema generará automáticamente su clase Binder correspondiente , que hereda IInterface, y tiene una clase abstracta estática Stub y una clase Proxy dentro de Stub. Entre ellos, Stub hereda la clase Binder, por lo que Stub en AIDL es un objeto Binder.

aglutinante:

Desde el punto de vista del código, Binder es una clase en el código fuente del sistema Android, que implementa la interfaz IBinder;

Desde la perspectiva de IPC, Binder es un método de comunicación entre procesos en Android;

Desde la perspectiva de Android Framework, Binder es un puente para que ServiceManager conecte varios Administradores (ActivityManager, WindowManager, etc.) y el correspondiente ManagerService;

Desde la perspectiva de la capa de aplicación de Android, Binder es el medio de comunicación entre el cliente y el servidor. Cuando se vincula el Servicio, el servidor devolverá un objeto Binder que contiene la llamada de servicio del servidor. A través de este objeto Binder, el cliente puede comunicarse con el servidor. Los servicios aquí incluyen servicios ordinarios y servicios basados ​​en AIDL.

El papel de AIDL es realizar la comunicación entre procesos y el método de uso es muy simple.Su modo de diseño es una arquitectura C/S típica. El cliente obtiene el objeto IBinder del servidor vinculando el servidor. Este objeto IBinder es el proxy en el modo proxy (o el puntero en la voz c, apuntando al servidor). Luego, el cliente puede enviar datos al servidor a través del método de transacción a través del objeto proxy, realizando la comunicación entre procesos.

2.1 Intención

Ejemplo de uso:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.putData...  //放一些你需要传递的数据
ComponentName componentName = new ComponentName("com.lucas.test", "com.lucas.test.Main2Activity");//要跳转的包名以及类名
intent.setComponent(componentName);
startActivity(intent);

Desventajas: la intención solo puede pasar objetos simples y los objetos deben implementar la interfaz Pacelable para la serialización.

Tres: Restricciones de datos de carpeta (suplementaria)

Motivos del límite de transferencia de datos de Binder:

  • 1. Habrá múltiples subprocesos de Binder en cada proceso, y estos subprocesos de Binder comparten el espacio de memoria de 1M-8K abierto cuando se creó el proceso, por lo que cuando cada subproceso de Binder transfiere datos, es imposible transferir 1M-8K;
  • 2. Además, en esta parte del espacio de memoria abierto, habrá algunas pilas y bloques de código que ocupan parte de la memoria.

Aviso

  • Nota 1: para los procesos de usuario ordinarios de la bifurcación Zygote, el tamaño de memoria de Binder asignado es inferior a 1 M. Para ser precisos, este límite se define #define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))en frameworks/native/+/4d2f4bb/libs/binder/ProcessState.cppla clase. Si los datos transmitidos superan este tamaño, el sistema informará un error, porque Binder en sí está diseñado para una comunicación frecuente y flexible entre procesos, no para copiar datos de gran tamaño.

referencia

Una pregunta de la entrevista: Uso de AIDL para transferir un archivo 2M entre procesos: https://juejin.cn/post/6990379493235884062

Límite de tamaño de datos de transferencia de intención de Android: https://blog.csdn.net/u011033906/article/details/117276922

Comunicación entre procesos de Android - (diez) límite de datos de transmisión del mecanismo Binder - el grupo de subprocesos Binder culpable: https://blog.csdn.net/nihaomabmt/article/details/116701810

Supongo que te gusta

Origin blog.csdn.net/LucasXu01/article/details/131765411
Recomendado
Clasificación