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 AndroidManifest
especificando Android:process
atributos 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 otrasshareUID
maneras 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:
- Los miembros estáticos y el modo singleton fallan completamente
- El mecanismo de sincronización del hilo es completamente inválido
- La fiabilidad de SP (SharedPreference) disminuirá
- Aplicación creada varias veces
1.3 Métodos para compartir datos
Si necesita un Application
servicio determinado Service
, Provider
o de Activity
otro intercambio de datos a cabo las siguientes tres maneras:
- Exposición completa: uso
android:exported="true"
, una vez configuradotrue
, estará completamente expuesto, y los datos expuestos pueden ser llamados por otros procesos de aplicación. Sin el usoandroid:exported
deService
,Provider
oActivity
, su defectoexported
valorfalse
, pero si esta vez se estableceintent 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 manifiestouse-permission
para 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
shareUserID
para 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 sistemaShareUID
, como Contacto, no se requiere la firma de un tercero. 3
1.4 Introducción a los conceptos básicos de IPC
Serialiazable
Con Parcelable
:
- Serialización: el proceso de convertir objetos en bytes
Serialiazable
: Interfaz de serialización proporcionada por JavaParcelable
: Interfaz de serialización proporcionada por Android
Serialiazable
Y Parcelable
la diferencia entre : Serialiazable
simple pero requiere una gran cantidad de operaciones de E / S, Parcelable
el 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 :
- Para utilizar
Bundle
- Usar uso compartido de archivos
- Para utilizar
SharedPreferences
- Para utilizar
Messenger
- Para utilizar
AIDL
- Para utilizar
ContentProvider
- Usar
Binder
grupo de conexiones - Transmitir
- Enchufe
- Tubería
2.1 Usando Messenger
Messenger
Conocido como el mensajero, a menudo se Message
usa junto con la comunicación entre procesos. La capa inferior es el Binder
embalaje simple correcto
- Pasos
- Crear una
Service
, enService
elonBind
retorno en unIBinder
sujeto. - En
AndroidManifest
la declaración del servicio, y el servicio sobre otro proceso - Por
bindService
servicio vinculante - Cree un
ServiceConnection
objeto en el cliente , use elIBinder
objeto devuelto por el servidor para crear unoMessenger
, queMessenger
es el servidorMessenger
, puedeMessenger
enviar 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 unHandler
objeto en el cliente , luego crear un cliente a partir del objetoMessenger
, luego enviar el cliente al servidor a través demessage.replyTo
5Messenger
, luego obtener la creación del cliente en el servidorMessenger
y enviar los datos a través de Messenger Al cliente, para que el servidor transmita datos al cliente) - Al
mMessenger.send(message)
enviar datos al servidor, se logra la comunicación entre procesos.
- Código para
la creación de unaService
, enService
elonBind
retorno en unIBinder
sujeto.
/**
* 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 AndroidManifest
la 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:
2.2 Usando Bundle
Bundle
Es un final
tipo 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
SharedPreferences
No 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. SharedPreferences
Existen 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
,SharedPreferences
las lecturas y escrituras frecuentes en procesos cruzados pueden hacer que se pierdan todos los datos. Según las estadísticas en línea,SharedPreferences
habrá aproximadamente 1 de cada 10,000 tasas de daños. - Se carga lentamente .
SharedPreferences
La 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 un100KB
elSP
archivo leído latencia, aproximadamente50 ~ 100ms
, y sugieren que se inicia a principios de un proceso de pre-carga utilizada en elSP
archivo. - Escribe en su totalidad . Tanto si se trata
commit()
oapply()
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, noSP
hemos fusionado múltiples cambios en uno, lo cual es una de las razones importantes del bajo rendimiento. - Caton . Como se proporciona un
apply
mecanismo 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 aonPause
alguna otra ocasión, el sistema obligará a todos losSharedPreferences
objetos 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, inclusoANR
, a partir de datos en línea,SP
Caton contabilidad generalmente superar5%
.
Por las razones anteriores, no se recomienda utilizar la SharedPreferences
comunicación entre procesos, especialmente la SharedPreferences
comunicació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
, ContentProvider
etc.
AIDL
El uso simple es visible: uso simple AIDL