Colección de citas famosas - Slogan de motivación - ¿En qué proceso se ejecuta Android Broadreceiver?

¿En qué proceso se ejecuta Android Broadreceiver?

Los receptores de transmisión se ejecutan en el hilo de la interfaz de usuario.

La siguiente introducción proviene del manual de aprendizaje de Android. El manual de aprendizaje de Android contiene 9 capítulos y 108 ejemplos. Puede leer los documentos del código fuente a voluntad. Todos los ejemplos son interactivos y ejecutables. La estructura de directorios de Android Studio y está resaltada. Los códigos y documentos se muestran mediante diagramas de estructura de documentos, que se pueden ubicar rápidamente. Descargue desde 360 ​​Mobile Assistant, hay un shell en el ícono

1. Descripción general del mecanismo de transmisión de Android

La transmisión de Android se divide en dos aspectos: emisor de transmisión y receptor de transmisión. BroadcastReceiver se refiere al receptor de transmisión (receptor de transmisión). Como método de comunicación entre componentes de Android, la transmisión se puede utilizar en los siguientes escenarios:

1. Comunicación de mensajes dentro del mismo componente dentro de la misma aplicación (entre uno o varios subprocesos

2. Comunicación de mensajes entre diferentes componentes dentro de la misma aplicación (proceso único);

3. Comunicación de mensajes entre diferentes componentes de la misma aplicación con múltiples procesos;

4. Comunicación de mensajes entre componentes entre diferentes aplicaciones;

5. Comunicación de mensajes entre el sistema Android y la aplicación en circunstancias específicas.

Desde la perspectiva de los principios de implementación, la transmisión en Android utiliza el patrón de observador, un modelo de evento de publicación/suscripción basado en mensajes. Por lo tanto, desde una perspectiva de implementación, la transmisión en Android desacopla en gran medida al remitente y al receptor de la transmisión, lo que hace que el sistema sea más fácil de integrar y expandir. Los puntos clave del proceso de implementación específico se resumen a grandes rasgos a continuación:

1. El receptor de transmisión, BroadcastReceiver, se registra en AMS (Activity Manager Service) a través del mecanismo Binder. El remitente de la transmisión se registra con AMS a través del mecanismo de carpeta. AMS envía una transmisión

3. AMS encuentra un BroadcastReceiver que cumple con las condiciones correspondientes (IntentFilter/Permission, etc.) y envía la transmisión al correspondiente. cola de bucle de mensajes de BroadcastReceiver (generalmente Actividad);

4. La ejecución del bucle de mensajes obtiene esta transmisión y vuelve a llamar al método onReceive() en BroadcastReceiver. Para diferentes tipos de transmisión y diferentes métodos de registro de BroadcastReceiver, la implementación específica será diferente. Pero el proceso general es más o menos el mismo que el anterior.

Desde este punto de vista, el remitente y el receptor de la transmisión pertenecen a los dos extremos de la publicación y suscripción del mensaje respectivamente en el modo observador, y AMS pertenece al centro de procesamiento intermedio. La ejecución del remitente y el receptor de la transmisión es asincrónica. A la transmisión enviada no le importa si hay un receptor para recibirla y no está seguro de cuándo la recibirá el receptor. Obviamente, el proceso general es muy similar al de EventBus.

En los escenarios específicos donde se puede utilizar el mecanismo de transmisión enumerado anteriormente, se analiza la aplicabilidad en aplicaciones reales:

El primer escenario: dentro del mismo componente dentro de la misma aplicación Para mensaje comunicación (entre subprocesos únicos o múltiples), el mecanismo de transmisión definitivamente no se usará en aplicaciones reales (aunque se puede usar), ya sea usando alcance variable extendido, devoluciones de llamada basadas en interfaz o Handler-post / Handler- Message y otros Los métodos pueden manejar directamente tales problemas. Si se utiliza el mecanismo de transmisión, obviamente se sentirá un poco "matando el pollo" y parecerá demasiado "pesado";

La segunda situación: comunicación de mensajes dentro de la misma aplicación. entre diferentes componentes (proceso único). Para tales necesidades, en algunos casos complejos, es difícil confiar simplemente en devoluciones de llamada basadas en interfaz y otros métodos. En este caso, EventBus se puede utilizar directamente. en un proceso unificado, es muy adecuado para manejar tales necesidades y se puede desacoplar fácilmente. Puede consultar el documento "EventBus, una herramienta de comunicación entre componentes/controles de Android".

Situaciones tercera, cuarta y quinta: dado que implica comunicación de mensajes entre diferentes procesos, es muy apropiado utilizar el mecanismo de transmisión de acuerdo con el negocio real en este momento. A continuación se resumen principalmente los puntos de conocimiento específicos en la transmisión de Android.

2.BroadcastReceiver

BroadcastReceiver personalizado

Un receptor de transmisión personalizado necesita heredar la clase base BroadcastReceivre e implementar el método abstracto onReceive(context, intent). Después de que el receptor de transmisión reciba la transmisión correspondiente, volverá automáticamente al método onReceive (...). De forma predeterminada, el receptor de transmisión también se ejecuta en el subproceso de la interfaz de usuario, por lo que no se pueden realizar operaciones que consuman mucho tiempo en el método onReceive. De lo contrario, se producirá ANR. En términos generales, según las necesidades comerciales reales, el método onReceive implicará interacciones con otros componentes, como el envío de notificaciones, el inicio de servicios, etc.

El siguiente fragmento de código es una personalización simple de un receptor de transmisión:

1 clase pública MyBroadcastReceiver extiende BroadcastReceiver {

2 pública estática final String TAG = " MyBroadcastReceiver ";

3 public static int m = 1;

4

5 ?@Override

6 public void onReceive(Contexto , Intención intención) {

7 Log.w(TAG, "intención:" + intención);

8 Nombre de cadena = intención.getStringExtra("nombre");

9 Log.w(TAG, "nombre:" + nombre + " m=" + m);

10 m++;

11

12 Paquete paquete = intent.getExtras();

13

14 ?}

15 }

Tipo de registro de BroadcastReceiver

BroadcastReceiver generalmente se puede dividir en dos tipos de registro: registro estático y registro dinámico.

1). Registro estático:

Regístrese directamente en el archivo AndroidManifest.xml.

Las reglas son las siguientes:

android:exported=["true"]

android:icon="recurso dibujable"

android:label="recurso de cadena"

android:name="cadena"

android :permiso= "cadena"

android:process="cadena"

.

. ellos, debes prestar atención a los Atributos

android:exported? - ¿Puede este receptor de transmisión recibir transmisiones de otras aplicaciones? El valor predeterminado de este atributo es un poco interesante. Su valor predeterminado está determinado por si existe. un filtro de intención en el receptor. Si hay un filtro de intención, el valor predeterminado es verdadero; de lo contrario, es falso. (De manera similar, el valor predeterminado de este atributo en actividad/servicio también sigue esta regla). Al mismo tiempo, debe tenerse en cuenta que la configuración de este valor se basa en la aplicación o la identificación del usuario de la aplicación, no en el proceso (en una aplicación). puede contener múltiples procesos);

android:name?——El nombre de clase de este broadcastReceiver;

android:permission?——Si está configurado, el remitente de la transmisión con los permisos correspondientes envía Las transmisiones pueden ser recibidas por este broadcastReceiver;

android:process?——El proceso en el que se ejecuta broadcastReceiver. El valor predeterminado es el proceso de la aplicación. Puede especificar un proceso independiente (los cuatro componentes básicos de Android pueden especificar su propio proceso independiente a través de este atributo)

Los formularios de registro comunes son:

Entre ellos, intent-filter especifica que este receptor de transmisión se utilizará para recibir un tipo de transmisión específico. El dado en este ejemplo se utiliza para recibir transmisiones enviadas por el propio sistema cuando cambia el estado de la red o cuando se inicia. Cuando esta aplicación se inicia por primera vez, el sistema creará automáticamente una instancia de MyBroadcastReceiver y lo registrará en el sistema.

A menudo se decía: incluso si la aplicación se ha cerrado, el receptor de transmisión registrado estáticamente aún puede recibir la transmisión correspondiente, pero es posible que esta descripción ya no sea cierta a partir de Android 3.1. Análisis específico Ver detalles más adelante. en este artículo.

2). Registro dinámico:

Durante el registro dinámico, no es necesario registrar el componente en AndroidManifest.

BroadcastReceiver se puede registrar dinámicamente en el programa llamando a la función RegisterReceiver de Context directamente en el código. La definición de RegisterReceiver es la siguiente:

1 RegisterReceiver (receptor BroadcastReceiver, filtro IntentFilter)

2 RegisterReceiver (receptor BroadcastReceiver, filtro IntentFilter, String broadcastPermission, programador Handler)

Los ejemplos de escritura típicos son los siguientes:

1 clase pública MainActivity extiende la actividad {

2 cadena final estática pública BROADCAST_ACTION = "com.example.corn";

3 BroadcastReceiver privado mBroadcastReceiver;

4

5 ?@Override

6 protected void onCreate(Bundle saveInstanceState) {

7 super.onCreate(savedInstanceState);

8 ?setContentView(R.layout.activity_main);

9

10 mBroadcastReceiver = nuevo MyBroadcastReceiver();

11 IntentFilter intentFilter = nuevo IntentFilter();

12 ?intentFilter.addAction(BROADCAST_ACTION);

13 ?registerReceiver(mBroadcastReceiver, intentFilter);

14 ?}

15

16 ?@Override

17 protected void onDestroy() {

18 super. onDestroy() ;

19 ?unregisterReceiver(mBroadcastReceiver);

20 ?}

21

22 }

Nota: En todos los diseños relacionados con el modo observador en Android, una vez involucrado el registro, se deberá solicitar la baja en el momento correspondiente. Por lo tanto, el ejemplo anterior requiere unregisterReceiver(mBroadcastReceiver) en el retorno de onDestroy().

Cuando se crea una instancia de esta actividad, MyBroadcastReceiver se registrará dinámicamente en el sistema. Cuando se destruye esta Actividad, MyBroadcastReceiver registrado dinámicamente ya no recibirá las transmisiones correspondientes.

3. Transmisión y tipo de transmisión

A menudo se dice que "enviar transmisión" y "recibir" en la superficie, la transmisión es una entidad en el mecanismo de transmisión de Android. De hecho, esta entidad en sí misma no existe como el llamado objeto de "difusión", sino que se expresa como una "intención". El proceso de definición de transmisión es en realidad el proceso de definición de la "intención" de transmisión correspondiente, y luego la "intención" se envía a través del remitente de la transmisión. Después de ser recibida por el BroadcastReceiver correspondiente, se volverá a llamar a la función onReceive ().

El siguiente fragmento de código muestra el proceso de definición de una transmisión normal y lo envía. Entre ellos, setAction(..) corresponde a la acción en intentFilter en BroadcastReceiver.

1 Intent intent = new Intent();

2 intent.setAction(BROADCAST_ACTION);

3 intent.putExtra("nombre", "qqyumidi" );

4 sendBroadcast(intent);

Según la forma en que se envía la transmisión, se puede dividir en los siguientes tipos:

1.Difusión normal : Transmisión ordinaria

2.System Broadcast: transmisión del sistema

3.Transmisión ordenada: transmisión ordenada

4.Sticky Broadcast: transmisión fija (en android 5.0/ Quedó obsoleto en api 21 y ya no se recomienda. En consecuencia, existe una transmisión ordenada fija, que también quedó obsoleta)

5. Difusión local: transmisión dentro de la aplicación

. A continuación se resumen por separado varios tipos de métodos de envío y sus características.

1).Difusión normal: Difusión normal

La difusión normal se define aquí como: la intención definida por el propio desarrollador, con context.sendBroadcast_"AsUser"(intención,... )forma. Los métodos específicos que se pueden utilizar son:

sendBroadcast(intent)/sendBroadcast(intent, ReceiverPermission)/sendBroadcastAsUser(intent, userHandler)/sendBroadcastAsUser(intent, userHandler, ReceiverPermission).

Las transmisiones ordinarias serán recibidas por los intereses registrados correspondientes (coincidencia de filtro de intención) y el orden no está ordenado. Si existen requisitos de permiso correspondientes al enviar una transmisión, BroadCastReceiver también necesita tener los permisos correspondientes si desea recibir esta transmisión.

2).Transmisión del sistema: Transmisión del sistema

Hay múltiples transmisiones del sistema integradas en el sistema Android, siempre que implique el funcionamiento básico del teléfono móvil, la transmisión del sistema correspondiente. básicamente se emitirá. Tales como: inicio, cambios de estado de la red, toma de fotografías, apagado y encendido de pantalla, iluminación insuficiente, etc. Cada transmisión del sistema tiene un filtro de intención específico, que incluye principalmente acciones específicas. Una vez enviada la transmisión del sistema, será recibida por el BroadcastReceiver correspondiente. El sistema envía automáticamente transmisiones del sistema cuando ocurre un evento específico dentro del sistema.

3) Transmisión ordenada: transmisión ordenada

El "ordenado" en la transmisión ordenada se refiere al receptor de transmisión y se refiere a la información enviada por BroadcastReceiver en orden.

El proceso de definición de transmisión ordenada es el mismo que el de transmisión ordinaria, excepto que su método de envío principal se convierte en: sendOrderedBroadcast (intención, receptorPermiso, ...).

Para la transmisión ordenada, sus características principales se resumen a continuación:

1>Cuando varios BroadcastReceivers actualmente registrados y válidos reciben transmisiones ordenadas, se reciben en orden. El orden de precedencia es el siguiente: Ordene todos los BroadcastReceivers registrados dinámicamente y estáticamente válidos en el sistema actual de acuerdo con el valor del atributo de prioridad de mayor a menor. Para transmisiones dinámicas y transmisiones estáticas con la misma prioridad, las transmisiones dinámicas se clasificarán en primer lugar.

2>El BroadcastReceiver que recibe primero puede truncar la transmisión ordenada para que el BroadcastReceiver posterior ya no reciba la transmisión, o la transmisión se puede modificar para que el BroadcastReceiver posterior pueda analizar la transmisión después de recibirla incorrectamente. valor del parámetro. Por supuesto, en general, no se recomienda realizar tales operaciones en transmisiones ordenadas, especialmente transmisiones ordenadas en el sistema.

4) Transmisión fija: transmisión fija (obsoleta en Android 5.0/api 21 y ya no se recomienda su uso. En consecuencia, existe una transmisión fija ordenada, que también ha quedado obsoleta).

Dado que ha quedado obsoleto, no se realizarán más resúmenes aquí.

5) Transmisión local: transmisión dentro de la aplicación (la aplicación de la aplicación aquí está limitada por el proceso de solicitud de la aplicación)

Como se puede ver en la descripción anterior, las transmisiones en Android pueden Los procesos cruzados o incluso la aplicación entre procesos se comunican directamente y el registro se exporta. Si hay un filtro de intención, el valor predeterminado es verdadero, lo que puede causar riesgos de seguridad de la siguiente manera:

1. puede enviar mensajes dirigidos a las transmisiones de la aplicación actual que coincidan con el filtro de intención, lo que hace que la aplicación actual reciba transmisiones y las procese continuamente;

2. App para recibir transmisiones y obtener información específica de transmisiones.

En cualquier caso, estos riesgos de seguridad existen. Por lo tanto, la solución más común para aumentar la seguridad es:

1. Para transmisiones enviadas y recibidas dentro de la misma aplicación, establezca artificialmente el atributo exportado en falso para que las transmisiones no enviadas dentro de la aplicación no se reciban.

2. Al enviar y recibir transmisiones, agregue los permisos correspondientes para la verificación de permisos;

3. Al enviar transmisiones, especifique la ubicación donde se encuentra el receptor de transmisión específico. especificado a través de intent.setPackage (nombre del paquete), de modo que esta transmisión solo se envíe al receptor de transmisión válido coincidente en la aplicación de este paquete.

La transmisión dentro de la aplicación puede entenderse como una forma de transmisión local. El remitente y el receptor de la transmisión pertenecen a la misma aplicación. En las necesidades comerciales reales, es posible que sea necesario utilizar la transmisión dentro de la aplicación. Al mismo tiempo, la razón por la que se utiliza la transmisión dentro de la aplicación en lugar de la transmisión global es más para considerar los problemas de seguridad en el mecanismo de transmisión de Android.

En comparación con la transmisión global, las ventajas de la transmisión dentro de la aplicación son:

1. Mayor seguridad

2.

Con este fin, el paquete de compatibilidad de Android v4 proporciona una clase LocalBroadcastManager encapsulada, que se utiliza para manejar de manera uniforme los problemas de transmisión dentro de la aplicación. El método de uso es casi el mismo que el de la transmisión global habitual, excepto el registro. /cancelación Al registrar un receptor de transmisión y enviar una transmisión, el contexto de llamada se convierte en una instancia única de LocalBroadcastManager.

El fragmento de código es el siguiente:

1 //registerReceiver(mBroadcastReceiver, intentFilter);

2 //Registrar el receptor de transmisión en la aplicación

3 localBroadcastManager = LocalBroadcastManager.getInstance(this);

4 localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);

5

6 // unregisterReceiver(mBroadcastReceiver) ;

7 //Anular el registro del receptor de transmisión en la aplicación

8 localBroadcastManager.unregisterReceiver(mBroadcastReceiver);

9

10 Intención intención = nueva Intención();

11 intent.setAction(BROADCAST_ACTION);

12 intent.putExtra("nombre", "qqyumidi");

13 //sendBroadcast(intent);

14 //Enviar transmisión en la aplicación

15 localBroadcastManager.sendBroadcast(intent); Diferentes métodos de registro El tipo de contexto específico en la devolución de llamada del receptor de transmisión onReceive(context, intent)

1). Para un ContextReceiver registrado estáticamente, el contexto en la devolución de llamada onReceive(context, intent) se refiere específicamente a ReceiverRestrictedContext. ;

2). Para el ContextReceiver registrado dinámicamente de transmisión global, el contexto en la devolución de llamada onReceive (contexto, intención) se refiere específicamente al contexto de actividad;

3). ContextReceiver registrado dinámicamente a través de LocalBroadcastManager, el contexto en la devolución de llamada onReceive(context, intent) se refiere específicamente al contexto de la aplicación.

Nota: Las transmisiones dentro de la aplicación enviadas por LocalBroadcastManager solo pueden ser recibidas por ContextReceivers registrados dinámicamente a través de LocalBroadcastManager (Los ContextReceivers registrados estática o dinámicamente de otras maneras no se pueden recibir).

5. Cambios importantes de API relacionados con el mecanismo de transmisión en diferentes versiones de API de Android

1). La transmisión fija y la transmisión fija ordenada caducarán en Android 5.0/API nivel 21. ya no se recomienda su uso;

2)". Incluso si la aplicación se ha cerrado, el receptor de transmisión registrado estáticamente aún puede recibir la transmisión correspondiente, pero es posible que esta descripción no esté disponible a partir de Android 3.1 Restablecer "

A partir de Android 3.1, el sistema ha agregado parámetros a los indicadores relacionados con la intención y la transmisión, a saber, FLAG_INCLUDE_STOPPED_PACKAGES y FLAG_EXCLUDE_STOPPED_PACKAGES.

FLAG_INCLUDE_STOPPED_PACKAGES: Contiene paquetes detenidos (detenidos: es decir, el proceso en el que se encuentra el paquete ha salido)

FLAG_EXCLUDE_STOPPED_PACKAGES: No incluye paquetes detenidos

Las razones principales son las siguientes:

Desde Android 3.1, el propio sistema ha agregado un seguimiento de si todas las aplicaciones se están ejecutando actualmente. Al enviar una transmisión, sin importar qué tipo de transmisión sea, el sistema agrega directamente la bandera con el valor FLAG_EXCLUDE_STOPPED_PACKAGES de forma predeterminada. Como resultado, incluso un receptor de transmisión registrado estáticamente no puede recibir transmisiones para aplicaciones cuyos procesos hayan cerrado.

Para obtener más detalles, consulte la documentación oficial de Android: /about/versions/android-3.1.html#launchcontrols

Por lo tanto, para las transmisiones del sistema, dado que se emiten directamente dentro del sistema, esta intención no se puede cambiar el valor del indicador, por lo tanto, a partir de 3.1, para el BroadcastReceiver registrado estáticamente que recibe transmisiones del sistema, si el proceso de la aplicación ha salido, la transmisión no se recibirá.

Pero para transmisiones personalizadas, puede sobrescribir este indicador en FLAG_INCLUDE_STOPPED_PACKAGES, de modo que el BroadcastReceiver registrado estáticamente pueda recibir la transmisión e iniciar el proceso de solicitud incluso si el proceso de la aplicación ha cerrado. Sin embargo, este BroadcastReceiver es nuevo. creado.

1 Intent intención = new Intent();

2 intent.setAction(BROADCAST_ACTION);

3 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); p>

4 intent.putExtra("name", "qqyumidi");

5 sendBroadcast(intent);

Nota 1: Para el tipo de registro dinámico BroadcastReceiver, debido a Este registro y cancelación del registro se realiza en otros componentes (como Actividad), por lo que no se ve afectado por este cambio.

Nota 2: Antes de 3.1, creo que muchas aplicaciones pueden monitorear varias transmisiones del sistema a través de métodos de registro estáticos para realizar algún procesamiento comercial (por ejemplo, incluso si la aplicación se ha cerrado, aún puede recibirla, usted puede iniciar el servicio, etc.), después de 3.1, el cambio en el método de transmisión de aceptación de registro estático hará que dicha solución ya no sea factible. Por lo tanto, configurar el Servicio y la propia Aplicación en procesos diferentes se ha convertido en una alternativa viable para satisfacer dichas necesidades.