Prefácio
Este artigo apresenta principalmente a intenção do Android e analisa o processo de correspondência de consulta de intenção da perspectiva do código -fonte do Android.
Intten Introdução
O chinês da Intent significa "intenção", e a intenção é um conceito muito abstrato. Portanto, o sistema Android especifica claramente que uma intenção pode ser medida por dois aspectos.
Principais atributos: incluindo ação e dados. Entre eles, a ação é usada para representar a intenção de ação expressa pela intenção, e os dados são usados para representar os dados operados pela ação.
Atributos secundários: incluindo categoria, tipo, componente e extras. A categoria representa a categoria, o tipo representa o tipo de dados de dados e os componentes podem ser usados para especificar a resposta de uma intenção específica (por exemplo, especificando a intenção de ser uma classe em um pacote), e os extras são usados para transportar outros Informação.
Existem dois tipos principais de intenção no sistema Android, que mostram a intenção (intenção explícita) e intenção oculta (intenção implícita).
Intenção explícita: esse tipo de intenção indica claramente qual componente encontrar. No código, você pode bloquear o objeto de destino através do setClassName ou setComponent.
Intenção implícita: esse tipo de intenção não indica claramente qual componente iniciar, mas define a ação, os dados e a categoria para tornar o sistema o componente apropriado.
Em seguida, escreva dois exemplos de código para introduzir a intenção explícita e implicar INENT. O primeiro é a intenção explícita:
Private void startExplicitIntEntWithComponent () {intenção intenção = new Intent (); Intenção);} private void startExitIntentWithClassName () {Intent Intent = new Intent ();No entanto, a partir do código -fonte, descobri que o SetClassName também usava o componente nome para obter intenção explícita. O código -fonte é o seguinte:
Public Intent SetclassName (String Packagename, String ClassName) {MComponent = new ComponentName (packagename, ClassName);Em seguida, um exemplo de código da intenção implicada. Aqui, uso uma atividade para marcar algum filtro de intenção como exemplo e, em seguida, escrevo uma intenção de iniciá -lo.
<Atividade Android: name = ". SendIntentType"> <Intent-filter> <Ação Android: name = "JustTest"/> <Categoria Android: name = "JustCategory" </intent-f Ilter> </itivity>
No AndroidManifest.xml atualmente aplicado, o filtro de intenção é adicionado à classe SendIntentType. O código que inicia a atividade é o seguinte:
Private void startImplictIntent () {intenção intenção = new Intent ();No processo de correspondência do processo de intenção implícita, os três itens listados pelo Filtro de Intenção serão usados como padrão de referência.
Gerenciamento de informações de atividades
A partir da análise acima, pode -se observar que, no processo de intenção de correspondência do sistema, você primeiro precisa gerenciar todas as informações de atividade no sistema atual. As informações da atividade foram coletadas e gerenciadas pela PackageManagerService ao digitalizar apk. O código -fonte relacionado é o seguinte:
// Processar as informações atantes anexadas n = pkg.activities.size (); A .info.processname = fixProcessName (pkg.applicationInfo.processname, A.Info.processname, pkg.applicationInfo.uid);
No código acima, existem duas estruturas de dados importantes, conforme mostrado na figura abaixo.
Combinado com a estrutura de dados do código e a figura acima, pode ser visto:
Macitivitys é o tipo AtividadeIntentsolver. Há também uma variável de mactivies dentro dessa estrutura de dados.
Todas as informações relacionadas à informação obtidas do APK (incluindo o rótulo IntentFilter declaradas em XML) são salvas pelo PackageParser.Activity.
O código anterior chama a função de addatividade para concluir a publicidade de informações privadas. O código da função de addatividade é o seguinte:
Public Final Addactivity (PackageParser.Activity A, String Type) {Final Boolean SystemApp = IssystemApp (A.Info.ApplicationInfo); Int j = 0; / Prioridade do não -sistema APK deve ser 0 intenção.setPriority (0);} addFilter (intenção);}}Vamos dar uma olhada na função AddFilter. O código -fonte da função é o seguinte:
Public void addfilter (f f) {// mfilters para salvar todas as informações do IntentFilter mfilters.add (f); Tipo: "); if (nums == 0 && numt == 0) {registr_intent_filter (f.Actionitertor (), mactintofilter," ação: ");} if (numt! = 0) {filtro (f, f.ActionAtatrator (), Mtypedactintofilter, "typeDaction:");}}}}Existem várias estruturas de dados aqui.
Depois de entender a estrutura de dados aproximada, vamos dar uma olhada na implementação da função de registro_intent_filter:
Private final int register_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 ();Em seguida, é outra função AddFilter, que é obviamente uma carga pesada.
Private void addfilter (Arraymap <string, f [] mapa, nome da string, filtro) {f [] Array = map.get (nome); (Nome, Array); if (i <n) {Array [i] = filtro;} else {f [] newa = newsray ((n*3)/2); n] = filtro;De fato, o código ainda é muito simples. Se a matriz F não existir, crie uma matriz com uma capacidade de 2 e atribua o elemento nº 0 ao filtro.
Análise de consulta de correspondência de intenções
O cliente por meio da saída da Função de QueryIntentividades pelo ApplicationPackageManager para iniciar uma solicitação de consulta ao PackageManageerService.
@Override Public List <ConveInfo> QueryIntentActivities (intenção de intenção, int sinalizadores) {return quryIntititiesSer (intenção, sinalizadores, mcOntext.get userid ());} / ** @hide o mesmo que acima, mas para um usuário específico* / @override público Lista <ConveInfo> QueryIntentActivitiesSuser (intenção de intenção, sinalizadores int, intemimeid) ifNeeded (mcOntext.getContentResolver ()), sinalizadores, UserID);} Catch (remoteexception e) {lança a nova execução ("o gerenciador de pacotes); e); e); }Pode -se observar que a verdadeira implementação do QueryIntentActivities está no PackageManagerService.java.
Lista pública <ConveInfo> QueryIntentActivities (intenção de intenção, String ResolvedType, int sinalizadores, int userID) {if (! SuserManager.Exists)) Coleções.Emptylist (); "); ComponentNetName comp = Intent.getComponent (); if (comp == null) {if (intent.getSelector ()! = Null) {intent = intent.getSelect ou (); comp = intent.getComponent ();} } if (comp! Nulo) {final de resolução ri = novo resolveinfo (); nulo) {// Intenção implícita retorna mactivities.QueryIntent (intenção, resolução, sinalizadores, UserID);} Final Pa. CkageParser.package pkg = mpackages.get (pkgname); nome da intenção devolver mactivities.quryIntentForpAckage (intenção, resolução, sinalizadores, pkg.Activities, UserID);Pode -se observar que a implementação da intenção explícita é relativamente simples. Intenção implícita chamada Método de Queryintent.
Lista pública <ConVeInfo> QueryIntent (intenção de intenção, string ResolvedType, int sinalizadores, int userID) {if (! SuserManager.erid)) Return NULL; )! = 0, UserID);}Continue rastreando o método de Queryintent do IntentRESOLVER.java, o código -fonte é o seguinte:
Lista pública <R> QueryIntent (intenção intenção, String ResolvedType, Boolean DefaultOnly, Intimeric) {String Scheme = Intent.getscheme (); Rodadas de operação correspondente F [] FirstTyPecut = NULL; Slashpos = ResolvedType.indexOf ('/'); .Length ()! = Slashpos+2 || ResolvedType.Charat (Slashpos+1)! TIPO COMPRIMENTO. ;} // qualquer tipo */ *sempre se aplica, mas precisamos apenas fazer isso // se o tipo não foi almedy */ *. ) !! ); ;} // Se o intertão não especificar nenhum dado - um tipo MIME ou // URI - então estaremos procurando apenas dados vazios //. Null) {FirstTyPecut = MactionTofilter.get (Intent.get.get ()); SecondTyPecut! , Terceirote, finalista, UserID);} if (esquema! = Null) {Builtresolvelist (intenção, categorias, depuração, Defaultonly, ResolvedType, esquema, esquema, finalista, UserID);} Sortresults (finalista);O processo específico de correspondência de consulta é concluído pela função BuildResolvelist. Não posto o código para a implementação correspondente da consulta.