[IPC] Comunicación detallada entre procesos (IPC) en Android

1 Puntos de conocimiento requeridos

1.1 Procesos e hilos

Para entender la comunicación entre procesos, primero tiene que entender lo siguiente conocimiento Puntos 1 :

  • Proceso : de acuerdo con la descripción del sistema operativo, el proceso es la unidad más pequeña de asignación de recursos, un proceso puede contener múltiples subprocesos
  • Subprocesos : los subprocesos son la unidad más pequeña de programación de la CPU. Los subprocesos múltiples deben considerar los problemas de concurrencia.

1.2 Multiprocesos en Android

El multiproceso de Android se refiere a la situación en la que hay múltiples procesos en una aplicación. En Android, generalmente hay un proceso para una aplicación. Caso multiproceso 2 :

  • Una aplicación debe implementarse en modo multiproceso debido a sus propios motivos.
  • Para aumentar la memoria disponible para una aplicación, se utilizan múltiples procesos para obtener múltiples copias de espacio de memoria

Active el modo multiproceso AndroidManifestespecificando Android:processatributos en

<activity
	android:name=".SecondActivity"
	android:process=":twoprocess"></activity>
 <activity
 	android:name=".ThirdActivity"
 	android:process="com.yds.thirdprocess"></activity>
 	
  • Para “:”procesar el inicio del proceso de solicitud es de propiedad privada, los otros componentes de la aplicación no pueden correr con ella en el mismo proceso, en lugar de al principio de los datos de colon globales del proceso, aplicaciones de otras shareUIDmaneras y se pueden ejecutar en el mismo proceso.
  • shareUID: El sistema Android asignará un nivel diferente de UID a cada programa. Si necesita llamarse entre sí, solo se requiere el mismo UID. Esto hace que los datos compartidos tengan un cierto grado de seguridad. Cada software no puede obtener datos a voluntad Sí, y la misma aplicación tiene un solo UID, por lo que no hay ningún problema de derechos de acceso entre las aplicaciones.

En términos generales, el uso de múltiples procesos tendrá los siguientes problemas:

  1. Los miembros estáticos y el modo singleton fallan completamente
  2. El mecanismo de sincronización del hilo es completamente inválido
  3. La fiabilidad de SP (SharedPreference) disminuirá
  4. Aplicación creada varias veces

1.3 Métodos para compartir datos

Si necesita un Applicationservicio determinado Service, Providero de Activityotro intercambio de datos a cabo las siguientes tres maneras:

  • Exposición completa: uso android:exported="true", una vez configurado true, estará completamente expuesto, y los datos expuestos pueden ser llamados por otros procesos de aplicación. Sin el uso android:exportedde Service, Providero Activity, su defecto exportedvalor false, pero si esta vez se establece intent filter, el valor predeterminado es true.
  • Solicitud de permiso expuesta: si la aplicación A está configurada android:permission="xxx.xxx.xxx", debe usarla en el manifiesto use-permissionpara acceder a los elementos de la aplicación A.
  • Exposición privada: si una compañía ha fabricado dos productos y solo quiere llamarse entre ellos, entonces esta vez debe usar shareUserIDpara forzar que el Uid de los dos software sea el mismo. En este caso, debe usar un documento firmado con la firma de la compañía. Si usa un software propio del sistema ShareUID, como Contacto, no se requiere la firma de un tercero. 3

1.4 Introducción a los conceptos básicos de IPC

SerialiazableCon Parcelable:

  • Serialización: el proceso de convertir objetos en bytes
  • Serialiazable: Interfaz de serialización proporcionada por Java
  • Parcelable: Interfaz de serialización proporcionada por Android

SerialiazableY Parcelablela diferencia entre : Serialiazablesimple pero requiere una gran cantidad de operaciones de E / S, Parcelableel uso de relativamente compleja, sobre todo para la secuencia de la memoria, de alta eficiencia.

Binder:
Ver Mecanismo de comunicación entre procesos [IPC] Binder para más detalles

2 Realización de IPC

Hay varias formas de lograr IPC 4 :

  1. Para utilizarBundle
  2. Usar uso compartido de archivos
  3. Para utilizarSharedPreferences
  4. Para utilizarMessenger
  5. Para utilizarAIDL
  6. Para utilizarContentProvider
  7. Usar Bindergrupo de conexiones
  8. Transmitir
  9. Enchufe
  10. Tubería

2.1 Usando Messenger

MessengerConocido como el mensajero, a menudo se Messageusa junto con la comunicación entre procesos. La capa inferior es el Binderembalaje simple correcto

  • Pasos
  1. Crear una Service, en Serviceel onBindretorno en un IBindersujeto.
  2. En AndroidManifestla declaración del servicio, y el servicio sobre otro proceso
  3. Por bindServiceservicio vinculante
  4. Cree un ServiceConnectionobjeto en el cliente , use el IBinderobjeto devuelto por el servidor para crear uno Messenger, que Messengeres el servidor Messenger, puede Messengerenviar los datos del cliente al servidor (este método es pasar datos del cliente al servidor, si lo desea Para transferir datos desde el cliente, puede crear un Handlerobjeto en el cliente , luego crear un cliente a partir del objeto Messenger, luego enviar el cliente al servidor a través de message.replyTo5Messenger , luego obtener la creación del cliente en el servidor Messengery enviar los datos a través de Messenger Al cliente, para que el servidor transmita datos al cliente)
  5. Al mMessenger.send(message)enviar datos al servidor, se logra la comunicación entre procesos.
  • Código para
    la creación de una Service, en Serviceel onBindretorno en un IBindersujeto.
/**
 * Created by yds
 * on 2020/4/13.
 */
public class MessengerService extends Service {
    //服务端自己的信使,为了获取客户端数据
    private Messenger mMessenger;
    //客户端信使对象,为了将数据发送到客户端
    private Messenger cMessenger;
    @Override
    public IBinder onBind(Intent intent) {
        mMessenger = new Messenger(new MyHandler());
        System.out.println("MessengerService onBind");
        return mMessenger.getBinder();
    }

    class MyHandler extends Handler{
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0:
                    Message message = Message.obtain(null,1);
                    message.arg1 = 1000;
                    //获取客户端传递来的信使
                    cMessenger = msg.replyTo;
                    try {
                        //通过客户端信使发送服务端数据到客户端
                        cMessenger.send(message);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    System.out.println("MessengerService handleMessage");
                    break;
            }
        }
    }
}


En AndroidManifestla declaración del servicio, y el servicio sobre otro proceso

<service android:name=".MessengerService"
        android:process="com.yds.test.messengerservice"/>

Use Messenger para realizar una comunicación bidireccional entre el cliente y el servidor

public class MainActivity extends AppCompatActivity {
    //服务端信使,为了发送数据到客户端
    private Messenger mMessenger;
    //客户端自己的信使,为了获取服务端数据
    private Messenger cMessenger;

    private static class MyHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    System.out.println("Service Data: " + msg.arg1);
                    break;
            }
        }
    }

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mMessenger = new Messenger(service);
            cMessenger = new Messenger(new MyHandler());
            if (mMessenger != null) {
                Message msg = Message.obtain(null, 0);
                //将客户端自己的信使放在Message里传递到服务端
                msg.replyTo = cMessenger;
                try {
                    mMessenger.send(msg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mMessenger = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this, MessengerService.class);
        bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mServiceConnection);
    }
}

Ejecutar captura de pantalla:
Inserte la descripción de la imagen aquí

2.2 Usando Bundle

BundleEs un finaltipo y no se puede heredar. Implementa la interfaz Parcelable y es un tipo de mapa especial que admite la comunicación entre procesos.
El uso de Bundle para la comunicación entre procesos se logra realmente a través de Messenger + Message. El código central es el siguiente:

mMessenger = new Messenger(service);
Message msg = Message.obtain(null, 0);
Bundle bundle = new Bundle();
bundle.putString("IPC", "Bundle");
bundle.putInt("Number", 20);
msg.setData(bundle);
try {
    mMessenger.send(msg);
} catch (RemoteException e) {
    e.printStackTrace();
}

2.3 使用 Preferencias compartidas

SharedPreferencesNo es adecuado para almacenar grandes cantidades de datos y datos que cambian con frecuencia. Solo se puede usar para almacenamiento liviano. Los datos se pueden perder durante la alta lectura / escritura simultánea. SharedPreferencesExisten los siguientes problemas de rendimiento 6 :

  • El proceso cruzado no es seguro . Dado que no se usan bloqueos de proceso cruzado, incluso si se usan MODE_MULTI_PROCESS, SharedPreferenceslas lecturas y escrituras frecuentes en procesos cruzados pueden hacer que se pierdan todos los datos. Según las estadísticas en línea, SharedPreferenceshabrá aproximadamente 1 de cada 10,000 tasas de daños.
  • Se carga lentamente . SharedPreferencesLa carga del archivo utiliza subprocesos asíncronos y el subproceso de carga no ha establecido una prioridad. Si lee datos en este momento, debe esperar hasta el final del subproceso de carga del archivo. Esto lleva a los principales hilo espera para los problemas de bloqueo de rosca de baja prioridad, como un 100KBel SParchivo leído latencia, aproximadamente 50 ~ 100ms, y sugieren que se inicia a principios de un proceso de pre-carga utilizada en el SParchivo.
  • Escribe en su totalidad . Tanto si se trata commit()o apply()incluso si sólo cambiar una de las entradas, va a poner todo el contenido de todos los documentos escritos. E incluso si escribimos el mismo archivo varias veces, no SPhemos fusionado múltiples cambios en uno, lo cual es una de las razones importantes del bajo rendimiento.
  • Caton . Como se proporciona un applymecanismo de colocación de disco asíncrono (copia en disco) , los datos pueden perderse en caso de un choque u otras condiciones anormales. Así que cuando la aplicación recibe un sistema de difusión, o llamando a onPausealguna otra ocasión, el sistema obligará a todos los SharedPreferencesobjetos de datos de aterrizaje en el disco. Si no se completa, el hilo principal se bloqueará todo el tiempo. Esto es muy probable que cause Caton, incluso ANR, a partir de datos en línea, SPCaton contabilidad generalmente superar 5%.

Por las razones anteriores, no se recomienda utilizar la SharedPreferencescomunicación entre procesos, especialmente la SharedPreferencescomunicación entre procesos no es segura.

2.4 Uso de compartir archivos

Use múltiples procesos para leer y escribir el mismo archivo externo al mismo tiempo para lograr el propósito de la interacción de datos, el formulario de almacenamiento no está limitado: xml, texto, serialización de objetos, etc. Pero tiene defectos obvios: dado que el sistema Linux no tiene restricciones en la lectura y escritura simultánea de archivos, causará la falta de sincronización de datos, por lo que este método solo es adecuado para la comunicación entre procesos con bajos requisitos de sincronización de datos.

2.5 Usando AIDL

Para que otras aplicaciones accedan a los servicios proporcionados por esta aplicación, el sistema Android utiliza la llamada a procedimiento remoto (Remote Procedure Call,RPC). Al igual que muchas otras soluciones basadas en RPC, Android usa un lenguaje de definición de interfaz (Interface Definition Language,IDL)para exponer las interfaces de servicio. Se basan muchos métodos de comunicación IPC AIDL. Tales como Service, ContentProvideretc.

AIDLEl uso simple es visible: uso simple AIDL

Para continuar

Artículo de referencia


  1. Llevarte a comprender el mecanismo de IPC de Android↩︎

  2. Modo multiproceso en Android desarrollado por Android↩︎

  3. Mecanismo UID y proceso de compartir en Android↩︎

  4. Android cuenta con un mecanismo de comunicación de proceso cuatro: use Bundle para la comunicación entre procesos ↩︎

  5. Messenger: comunicación entre procesos mediante mensajes (uso de Message.replyTo ()) ↩︎

  6. SharedPreferences introducción y uso de las instrucciones del Android ↩︎

Publicado 139 artículos originales · elogiado 179 · 140,000 visitas

Supongo que te gusta

Origin blog.csdn.net/u013293125/article/details/105485223
Recomendado
Clasificación