Prefacio
Este artículo presenta principalmente la intención de Android y analiza el proceso de coincidencia de consultas de intención desde la perspectiva del código fuente de Android.
Introducción Inten
El chino de la intención significa "intención", y la intención es un concepto muy abstracto. Por lo tanto, el sistema Android especifica claramente que una intención puede medirse por dos aspectos.
Atributos principales: incluyendo acción y datos. Entre ellos, la acción se utiliza para representar la intención de acción expresada por la intención, y los datos se utilizan para representar los datos operados por la acción.
Atributos secundarios: incluyendo categoría, tipo, componente y extras. La categoría representa la categoría, el tipo representa el tipo de datos de datos, y los componentes se pueden usar para especificar la respuesta de una intención específica (por ejemplo, especificar la intención de ser una clase de clase bajo un paquete), y los extras se usan para llevar a otros información.
Hay dos tipos principales de intención en el sistema Android, que muestra la intención (intención explícita) y la intención oculta (intención implícita).
Intención explícita: este tipo de intención indica claramente qué componente encontrar. En el código, puede bloquear el objeto de destino a través de setClassName o setComponent.
Intención implícita: este tipo de intención no indica claramente qué componente comenzar, sino que establece la acción, los datos y la categoría para que la pantalla del sistema sea el componente apropiado.
A continuación, escriba dos ejemplos de código para introducir la intención de expllicit e implicarse en la entrada. El primero es la intención explícita:
Privado void startExplicitIntentWithComponent () {intent intent = new intent (); Intento);} private startExplicitIntentWithClassName () {intent intent = new intent ();Sin embargo, del código fuente, descubrí que SetClassName también usaba ComponentName para lograr una intención explícita. El código fuente es el siguiente:
Public Intent SetClassName (String PackageName, String ClassName) {mComponent = new ComponentName (PackageName, ClassName);Luego, un ejemplo de código de la intención de implicidad. Aquí uso una actividad para marcar algún filtro de intención como ejemplo, y luego escribo una intención para iniciarlo.
<Activity Android: name = ". SendIntentType"> <Tentent-Filter> <Action Android: name = "justTest"/> <category android: name = "justCategory" </Intent-F ilter> </Adity>
En AndroidManifest.xml se aplica actualmente, el filtro de intención se agrega a la clase SendIntentType. El código que inicia la actividad es el siguiente:
Privado startImplLictIntent () {intent intent = new intent ();En el proceso de coincidir el proceso de intención de Implicte, los tres elementos enumerados por el filtro de intención se utilizarán como estándar de referencia.
Gestión de la actividad de información
A partir del análisis anterior, se puede ver que en el proceso de intención de coincidencia del sistema, primero debe administrar toda la información de actividad en el sistema actual. La información de la actividad fue recopilada y administrada por PackagemanagerService al escanear APK. El código fuente relacionado es el siguiente:
// Procesar la información atural adjunta n = pkg.activities.size (); A .info.processname = FixProcessName (pkg.applicationInfo.processname, a.info.processname, pkg.applicationinfo.uid);
En el código anterior, hay dos estructuras de datos importantes, como se muestra en la figura a continuación.
Combinado con la estructura de datos del código y la figura anterior, se puede ver:
Macitivitys es el Tipo de ActivityIntentResolver. También hay una variable de Mactivies dentro de esta estructura de datos.
Toda la información relacionada con la información obtenida del APK (incluida la etiqueta IntentFilter declarada en XML) se guarda mediante paquetes de paquete.Activity.
El código anterior llama a la función de addactividad para completar la publicidad de la información privada. El código de la función AddActivity es el siguiente:
Public Final Void AddActivity (PackageParser.Activity A, String Type) {Final Boolean SystemApp = IssystemApp (a.info.ApplicationInfo); Int j = 0; / La prioridad de APK no del sistema debe ser 0 Intent.SetPriority (0);} addfilter (intento);}}Echemos un vistazo a la función addfilter. El código fuente de la función es el siguiente:
Public void addfilter (f f) {// mfilters para guardar toda la información de intentfilter mfilters.add (f); Tipo: "); if (nums == 0 && numt == 0) {registro_intent_filter (f.ActionSiterTor (), mActinToFilter," Action: ");} if (numt! = 0) {Filter (F, F.ActionSitatrator (), Mtypedactintofilter, "typedaction:");}}}}Aquí hay varias estructuras de datos más.
Después de comprender la estructura de datos aproximada, echemos un vistazo a la implementación de la función de Register_intent_Filter:
Private final int registro_intent_filter (filtro, iterator <String> i, arraymap <string, f [] dest, string, string, if (i == null) {return 0;} int num = 0; while (i.hasnext () ) {String name = ipxt ();Entonces es otra función addfilter, que obviamente es una carga pesada de la función.
Private Final Void AddFilter (ArrayMap <String, F [] MAP, String Name, Filter) {f [] Array = MAP.GET (Nombre); (Nombre, matriz); if (i <n) {array [i] = filtro;} else {f [] newa = Newsray ((n*3)/2); n] = filtro;De hecho, el código sigue siendo muy simple. Si la matriz F no existe, cree una matriz con una capacidad de 2 y asigne el elemento No. 0 al filtro.
Análisis de consultas de coincidencia de intenciones
El cliente a través de la salida de la función de consulta Interpretación de Aplication PackageManager para iniciar una solicitud de consulta al PackageManAgreService.
@Override Public List <SolveInfo> QueryIntentAtAdAdAdAdAdAdtivities (intención intención, int flags) {return QuryIntititityAser (intent, flags, mcontext.get userId ());} / ** @hide lo mismo que anteriormente pero para un usuario específico* / @override público público LIST <ROSCONVEINFO> QUERYIntentActivitiesAsUser (intencion intent, int flags, intimeId) ifNeeded (mContext.getContentResolver ()), flags, userId);} catch (remoteException e) {throw throw runtimeException ("Manager de paquetes ha muerto", E);} }Se puede ver que la implementación real de QueryIntentActivities está en el PackageManagerService.java.
Lista pública <solveInfo> QueryIntentActivities (intención intención, cadena resuelveType, int fra. "); ComponentNetName comp = intent.getComponent (); if (comp == null) {if (intent.getSelector ()! = Null) {intent = intent.getSelect o (); comp = intent.getComponent ();} } if (comp! = null) {// Explicit's Intent, obtenga directamente la Actividad Correspondiente en la lista final <solveInfo> list = new ArrayInfo> (1); NULL) {final resolveInfo ri = new ResolveInfo (); nulo) {// Mactivities de retorno de intención implícito Nombre de la intención MactivitiesSe puede ver que la implementación de la intención explícita es relativamente simple. Intención implícita llamada Método de consulta.
Lista pública <SolveInfo> QueryIntent (intención intención, string resoledType, int fra. )!
Continúe rastreando el método de consulta de intentresolver.java, el código fuente es el siguiente:
Lista pública <r> QueryIntent (intención intencional, string res dolEdType, boolean Defaultonly, intimérico) {string esquema = intent.getScheme (); rondas de operación coincidente f [] FirstTypecut = NULL; SlashPos = resoledType.indexof ('/'); .length ()! = slashpos+2 || Tipo de coincidencia. ;} // Los tipos */ *siempre se aplican, pero solo necesitamos hacer esto // si el tipo no era Almedy */ *. ) !! ); ;} // Si el Intert no especifica ningún dato, ya sea un tipo MIME o // un URI, entonces solo estaremos buscando datos de vacío //. Nulo) {FirstPeCut = MACTIONTOFILTER.GET (intent.get.get ()); SECHTTYPECUT! = NULL) {BuildResOlist (intención, categorías, depuración, defaultyly, esquema, esquema, s econdtypecut, finallist, userId);} if (tercera , ThirdTyPeCut, Finalist, UserId);} if (schemecut! = Null) {builtreSolvelist (intento, cate gories, depuración, defaultonly, resueldType, esquema, esquemecut, finalista, userID);} Sortresults (finalista);El proceso de coincidencia de consultas específico se completa con la función BuildResOlvelist. No publico el código para la implementación coincidente de la consulta.