page.title=Fundamentos de aplicativos @jd:body
Os aplicativos do Android são programados em linguagem de programação Java. As ferramentas Android SDK compilam o código — em conjunto com todos os arquivos de dados e recursos — em um APK, que é o pacote do Android, um arquivo de arquivamento com sufixo {@code .apk}. Os arquivos de APK contêm todo o conteúdo de um aplicativo do Android e são os arquivos que os dispositivos desenvolvidos para Android usam para instalar o aplicativo.
Depois de instalado em um dispositivo, cada aplicativo do Android é ativado em sua própria área de segurança:
Assim, o sistema Android implementa o princípio do privilégio mínimo. Ou seja, cada aplicativo, por padrão, tem acesso somente aos componentes necessários para a execução do seu trabalho e nada mais. Isso cria um ambiente muito seguro em que o aplicativo não pode acessar partes do sistema para o qual não tem permissão.
No entanto, sempre existe uma maneira de um aplicativo compartilhar dados com outros aplicativos e acessar serviços do sistema:
Essas são as informações básicas de como um aplicativo do Android existe dentro do sistema. O restante deste documento apresenta o leitor a:
Os componentes de aplicativo são os blocos de construção fundamentais de um aplicativo do Android. Cada componente é um ponto diferente pelo qual o sistema pode entrar no aplicativo. Nem todos os componentes são pontos de entrada reais para o usuário e alguns dependem uns dos outros, mas cada um existe como uma entidade independente e desempenha uma função específica — cada um é um bloco de construção exclusivo que ajuda a definir o comportamento geral do aplicativo.
Há quatro tipos diferentes de componentes de aplicativo. Cada tipo tem uma finalidade distinta e tem um ciclo de vida específico que define a forma pela qual o componente é criado e destruído.
A seguir apresentam-se os quatro tipos de componentes de aplicativos:
Uma atividade é implementada como uma subclasse de {@link android.app.Activity} — saiba mais sobre isso no guia do desenvolvedor Atividades.
Um serviço é implementado como uma subclasse de {@link android.app.Service} — saiba mais sobre isso no guia do desenvolvedor Serviços.
Os provedores de conteúdo são úteis para ler e gravar dados privados no aplicativo e não compartilhados. Por exemplo: o exemplo de aplicativo Note Pad usa um provedor de conteúdo para salvar notas.
Um provedor de conteúdo é implementado como uma subclasse de {@link android.content.ContentProvider} e precisa implementar um conjunto padrão de APIs que permitem a outros aplicativos realizar transações. Para obter mais informações, consulte o guia de desenvolvedor Provedores de conteúdo.
Os receptores de transmissão são implementados como subclasses de {@link android.content.BroadcastReceiver} e cada transmissão é entregue como um objeto {@link android.content.Intent}. Para obter mais informações, consulte a classe {@link android.content.BroadcastReceiver}.
Um aspecto exclusivo do projeto do sistema Android é que qualquer aplicativo pode iniciar um componente de outro aplicativo. Por exemplo: se você quiser que o usuário capture uma foto com a câmera do dispositivo, provavelmente haverá outro aplicativo que faz isso e o seu aplicativo poderá usá-lo, ou seja, não será necessário desenvolver uma atividade para capturar uma foto. Não é necessário incorporar nem mesmo vinculá-lo do aplicativo da câmera ao código. Em vez disso, basta iniciar a atividade no aplicativo da câmera que captura uma foto. Quando concluída, a foto até retorna ao aplicativo em questão para ser usada. Para o usuário, parece que a câmera é realmente parte do aplicativo.
Quando o sistema inicia um componente, ele inicia o processo daquele aplicativo (se ele já não estiver em execução) e instancia as classes necessárias para o componente. Por exemplo: se o aplicativo iniciar a atividade no aplicativo da câmera que captura uma foto, aquele aplicativo é executado no processo que pertence ao aplicativo da câmera e não no processo do aplicativo. Portanto, ao contrário dos aplicativos na maioria dos outros sistemas, os aplicativos do Android não têm um ponto de entrada único (não há a função {@code main()}, por exemplo).
Como o sistema executa cada aplicativo em um processo separado com permissões de arquivo que restringem o acesso a outros aplicativos, o aplicativo não pode ativar diretamente um componente a partir de outro aplicativo. No entanto, o sistema Android pode. Portanto, para ativar um componente em outro aplicativo, é preciso enviar uma mensagem ao sistema que especifique a intenção de iniciar um componente específico. Em seguida, o sistema ativa o componente.
Três dos quatro tipos de componente — atividades, serviços e receptores de transmissão — são ativados por uma mensagem assíncrona chamada intenção. As intenções vinculam componentes individuais entre si em tempo de execução (como mensageiros que solicitam uma ação de outros componentes), seja o componente pertencente ao aplicativo ou não.
A intenção é criada com um objeto {@link android.content.Intent}, que define uma mensagem para ativar um componente específico ou um tipo específico de componente — as intenções podem ser explícitas ou implícitas, respectivamente.
Para atividades e serviços, as intenções definem a ação a executar (por exemplo, "exibir" ou "enviar" algo) e podem especificar a URI dos dados usados na ação (entre outras coisas que o componente a iniciar precisa saber). Por exemplo: uma intenção pode transmitir uma solicitação de uma atividade para exibir uma imagem ou abrir uma página da web. Em alguns casos, é preciso iniciar uma atividade para receber um resultado; nesse caso, a atividade também retorna o resultado em um {@link android.content.Intent} (por exemplo, é possível emitir uma intenção para que o usuário selecione um contato pessoal e o retorne a você — a intenção de retorno contém uma URI que aponta para o contato selecionado).
Para receptores de transmissão, a intenção simplesmente define o anúncio que está sendo transmitido (por exemplo, uma transmissão para indicar que a bateria do dispositivo está acabando contém uma string de ação conhecida que indica "nível baixo da bateria").
O outro tipo de componente, o provedor de conteúdo, não é ativado por intenções. Em vez disso, ele é ativado por uma solicitação de um {@link android.content.ContentResolver}. O resolvedor de conteúdo manipula todas as transações diretas com o provedor de conteúdo para que o componente que executa as transações com o provedor não precise e, em vez disso, chama os métodos no objeto {@link android.content.ContentResolver}. Isso deixa uma camada de abstração entre o provedor de conteúdo e o componente que solicita informações (por segurança).
Há dois métodos separados para ativar cada tipo de componente:
Para obter mais informações sobre intenções, consulte o documento Intenções e filtros de intenções. Veja mais informações sobre a ativação de componentes específicos nos seguintes documentos: Atividades, Serviços, {@link android.content.BroadcastReceiver} e Provedores de conteúdo.
Antes de o sistema Android iniciar um componente de aplicativo, é preciso ler o arquivo {@code AndroidManifest.xml} (o arquivo de "manifesto") do aplicativo para que o sistema saiba se o componente existe. O aplicativo precisa declarar todos os seus componentes nesse arquivo, que deve estar na raiz do diretório do projeto do aplicativo.
O manifesto faz outras coisas além de declarar os componentes do aplicativo, por exemplo:
A principal tarefa do manifesto é informar ao sistema os componentes do aplicativo. Por exemplo: um arquivo de manifesto pode declarar uma atividade da seguinte forma:
<?xml version="1.0" encoding="utf-8"?> <manifest ... > <application android:icon="@drawable/app_icon.png" ... > <activity android:name="com.example.project.ExampleActivity" android:label="@string/example_label" ... > </activity> ... </application> </manifest>
No elemento <application>
, o atributo {@code android:icon} aponta para recursos de um ícone que identifica
o aplicativo.
No elemento <activity>
,
o atributo {@code android:name} especifica o nome da classe totalmente qualificada da subclasse de {@link
android.app.Activity} e o atributo {@code android:label} especifica uma string
a usar como a etiqueta da atividade visível ao usuário.
É preciso declarar todos os componentes desta forma:
<activity>
para atividades<service>
para serviços<receiver>
para receptores de transmissão<provider>
para provedores de conteúdoAtividades, serviços e provedores de conteúdo incluídos na fonte, mas não declarados no manifesto, não ficam visíveis para o sistema e, consequentemente, podem não ser executados. No entanto, receptores de transmissão podem ser declarados no manifesto dinamicamente no código (como objetos {@link android.content.BroadcastReceiver}) e registrados no sistema chamando-se {@link android.content.Context#registerReceiver registerReceiver()}.
Para obter mais informações sobre a estrutura do arquivo de manifesto de aplicativos, consulte a documentação O arquivo AndroidManifest.xml.
Conforme abordado acima, em Ativação de componentes, é possível usar uma {@link android.content.Intent} para iniciar atividades, serviços e receptores de transmissão. Isso pode ser feito nomeando-se explicitamente o componente-alvo (usando o nome da classe do componente) na intenção. No entanto, a verdadeira força das intenções reside no conceito de intenções implícitas. As intenções implícitas descrevem simplesmente o tipo de ação a executar (e, opcionalmente, os dados em que a ação deve ser executada) e permitem ao sistema encontrar e iniciar um componente no dispositivo que pode executar a ação. Se houver mais de um componente que possa executar a ação descrita pela intenção, o usuário selecionará qual deles usar.
Para o sistema identificar os componentes que podem responder a uma intenção, compara-se a intenção recebida com os filtros de intenções fornecidos no arquivo de manifesto de outros aplicativos do dispositivo.
Ao declarar uma atividade no manifesto do aplicativo, pode-se incluir filtros de intenções que declarem os recursos da atividade para que ela responda a intenções de outros aplicativos. Para declarar um filtro de intenções no componentes, adiciona-se um elemento {@code <intent-filter>} como filho do elemento de declaração do componente.
Por exemplo: se você estiver programando um aplicativo de e-mail com uma atividade de compor um novo e-mail, é possível declarar um filtro de intenções para responder a intenções "enviar" (para enviar um novo e-mail), assim:
<manifest ... > ... <application ... > <activity android:name="com.example.project.ComposeEmailActivity"> <intent-filter> <action android:name="android.intent.action.SEND" /> <data android:type="*/*" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> </application> </manifest>
Em seguida, se outro aplicativo criar uma intenção com a ação {@link android.content.Intent#ACTION_SEND} e passá-la para {@link android.app.Activity#startActivity startActivity()}, o sistema poderá iniciar a atividade de forma que o usuário possa rascunhar e enviar um e-mail.
Para obter mais informações sobre filtros de intenções, consulte o documento Intenções e filtros de intenções.
Existem vários dispositivos desenvolvidos para Android e nem todos apresentam os mesmos recursos e características. Para evitar que o aplicativo seja instalado em dispositivos que não contenham os recursos que o aplicativo necessita, é importante definir um perfil para os tipos de dispositivo compatíveis com o aplicativo. É preciso declarar os requisitos de dispositivo e software no arquivo de manifesto. A maior parte dessas declarações é somente informativa e o sistema não as lê, mas serviços externos, como o Google Play, as leem para oferecer uma filtragem aos usuários quando buscam esses aplicativos para seu dispositivo.
Por exemplo: se o aplicativo exige uma câmera e usa APIs introduzidas no Android 2.1 (API de nível 7), deve-se declarar esses requisitos no arquivo de manifesto da seguinte forma:
<manifest ... > <uses-feature android:name="android.hardware.camera.any" android:required="true" /> <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" /> ... </manifest>
Assim, dispositivos que não tenham câmera e tenham versão Android anterior a 2.1 não poderão instalar o aplicativo a partir do Google Play.
No entanto, também é possível declarar que o aplicativo usa a câmera como recurso não obrigatório. Nesse caso, o aplicativo precisa definir o atributo {@code required} como {@code "false"} e verificar em tempo de execução se o dispositivo tem câmera e desativar os recursos da câmera conforme o necessário.
Veja mais informações sobre o gerenciamento da compatibilidade do aplicativo com diferentes dispositivos no documento Compatibilidade do dispositivo.
Os aplicativos Android são compostos por mais do que somente códigos — eles requerem recursos separados do código-fonte, como imagens, arquivos de áudio e tudo o que se relaciona com a apresentação visual do aplicativo. Por exemplo: deve-se definir animações, menus, estilos, cores e o layout das interfaces do usuário da atividade com arquivos XML. O uso de recursos de aplicativo facilita a atualização de diversas características do aplicativo sem a necessidade de modificar o código e — fornecendo conjuntos de recursos alternativos — permite otimizar o aplicativo para diversas configurações de dispositivo (como idiomas e tamanhos de tela diferentes).
Para todo recurso incluído no projeto Android, as ferramentas de programação SDK definem um ID inteiro exclusivo que o programador pode usar para referenciar o recurso do código do aplicativo ou de outros recursos definidos no XML. Por exemplo: se o aplicativo contiver um arquivo de imagem de nome {@code logo.png} (salvo no diretório {@code res/drawable/}), as ferramentas de SDK gerarão um ID de recurso chamado {@code R.drawable.logo}, que pode ser usado para referenciar a imagem e inseri-la na interface do usuário.
Um dos aspectos mais importantes de fornecer recursos separados do código-fonte é a capacidade de fornecer recursos alternativos para diferentes configurações de dispositivo. Por exemplo: ao definir strings de IU em XML, é possível converter as strings em outros idiomas e salvá-las em arquivos separados. Em seguida, com base em um qualificador de idioma acrescentado ao nome do diretório do recurso (como {@code res/values-fr/} para valores de string em francês) e a configuração de idioma do usuário, o sistema Android aplica as strings de idioma adequadas à IU.
O Android aceita vários qualificadores para recursos alternativos. O qualificador é uma string curta incluída no nome dos diretórios de recurso para definir a configuração de dispositivo em que esses recursos serão usados. Outro exemplo: deve-se criar diferentes layouts para as atividades conforme a orientação e o tamanho da tela do dispositivo. Por exemplo: quando a tela do dispositivo está em orientação retrato (vertical), pode ser desejável um layout com botões na vertical, mas, quando a tela está em orientação paisagem (horizontal), os botões devem estar alinhados horizontalmente. Para alterar o layout conforme a orientação, pode-se definir dois layouts diferentes e aplicar o qualificador adequado ao nome do diretório de cada layout. Em seguida, o sistema aplica automaticamente o layout adequado conforme a orientação atual do dispositivo.
Para obter mais informações sobre os diferentes tipos de recursos a incluir no aplicativo e como criar recursos alternativos para diferentes configurações de dispositivo, leia Como fornecer recursos.