Android é um sistema multi-usuário onde cada aplicação possui seu próprio usuário. O sistema atribui os arquivos de cada aplicação ao usuário da aplicação de forma que cada aplicativo somente consiga ter acesso aos arquivos da própria aplicação. Cada aplicação executa em seu próprio processo e cada processo executa em uma máquina virtual isolada.É possível criar aplicações que executem com um mesmo usuário, executando no mesmo processo e compartilhando os arquivos. Para isto, é necessário que os aplicativos sejam assinados com as mesmas chaves.
As aplicações devem solicitar permissões para acesso os recursos do dispositivo. As permissões são concedidas ao usuário da aplicação.
Quando há necessidade de uma aplicação executar um componente de outra aplicação, como as aplicações são isoladas através de usuários únicos e seus processos, a aplicação deve informar a sua intenção de iniciar o componente de outra aplicação através de um objeto Intent e o sistema providenciará a execução deste componente e suas dependências.
Activity
É o ponto de interação com o usuário. Cada activity terá seu próprio layout e diagramação. Cada aplicação poderá possuir vários activities e estes são independentes entre si. Ao sair da aplicação, é possível que o usuário retorne ao activity que estava ativo ao sair. Também é possível que um activity seja acionado por uma outra aplicação, se esta permitir, para, por exemplo, compartilhar algum conteúdo.
Um activity é implementado como uma subclasse da classe nativa Activity.
Service
É um componente da aplicação que permite que alguma ação seja executada em segundo plano, sem impactar a activity em primeiro plano. Neste componente, não há interação direta com o usuário. É possível criar uma interações entre activities e services.
Ao iniciar, o service informa ao sistema se este serviço deve ser executado de forma contínua (ex. reprodução musical) ou se pode ser interrompido quando o sistema necessitar de recursos e continuar quando o sistema estiver com recursos disponíveis.
Um service pode prover serviços a outros services. Nesta caso, o sistema faz o gerenciamento das dependências para garantir que os services necessários a execução de outro service esteja disponível quando este é executado.
Um service é implementado como uma subclasse da classe Service.
Broadcast receiver
É um componente que permite ao sistema publicar mensagens de interesse geral às aplicações. Este componente também não tem interface com o usuário, mas pode ser implementada uma notificação no status bar.
Também pode ser implementado um broadcast receiver que receba mensagem de um scheduler.
O sistema pode enviar mensagens mesmo que o processo não esteja em execução.
Um broadcast receiver é implementado como uma subclasse da classe BroadcastReceiver.
Content provider
O componente gerencia dados da aplicação que podem ser armazenados em arquivos, no dispositivo, na nuvem ou em qualquer localidade que o aplicativo possa ter acesso a dados.
O conteúdo são dados nomeados acessados pelo aplicativo através de um esquema de URI única
Alguns aspectos sobre o gerenciamento do conteúdo pelo sistema:
Não há necessidade da aplicação que criou a URI continuar em execução. Ele só é necessário que ela seja executada quando houver necessidade de recuperar os dados armazenados.
O modelo de segurança para acesso aos dados referenciados por uma URI são finamente controlados. Uma aplicação pode dar acesso temporário ao dado, sem dar acesso ao dado persistido.
Um content provider é implementado como uma subclasse da classe ContentProvider.
Três componentes poder ser ativados através de uma mensagem assíncrona da classe Intent: Activity, Service e Broadcast receiver
Um Intent pode ser criado através de um objeto da classe Intent, que defina a mensagem para iniciar um componente específico (explicit intent) ou um tipo específico de componente (implicit intent).
Para activities e services, um Intent define qual a ação será executada e pode especificar a URI do dado a ser processado. Em outros casos, pode retornar o resultado de um processamento ao acionar o activity que solicitou a informação.
Para broadcast receivers, o Intent define a mensagem a ser publicada.
Um Content provider é acionado por uma requisição efetuada através de um ContentResolver. O content resolver trata todas as transações com o content provider. Não são processadas chamadas diretas entre o content resolver e o content provider. Por questões de segurança uma camada de abstração é implementada entre os compomentes.
Cada tipo de compomente deve ser ativado através de métodos específicos:
Um Activity pode ser acionado ou receber uma novas informações passando um Intent através dos métodos startActivity() ou startActivityForResult(). O segundo método é utilizado quando se dejeja receber algum resultado do processamento.
Um Service pode ser acionado com o uso de uma classe JobScheduler para o Android 5.0 (API level 21) ou através da passagem de um Intent para o método StartService(). Você também pode fazer uma ligação a um serviço através da passagem de um Intent para o método BindService().
Um broadcast receiver pode ser acionado através da passagem de um Intent para métodos como sendBroadcast(), sendOrderedBroadcast() ou sendStickyBroadcast().
Uma query pode ser executada em um Content provider através da chamada do método query() em um ContentResolver.
Para maiores informações sobre a utilização de Intents, o documento Intents and Intent Filters pode ser consultado.
No arquivo manifest (AndroidManifest.xml), que fica na raiz do projeto, são declarados todos componentes do projeto e além destes:
as permissões de usuários necessárias para a aplicação (ex.: acesso à internet, acesso aos contatos, ...);
o nível mínimo de API necessário, baseado na API que a aplicação utiliza;
os recursos de hardware e software necessários para a execução da aplicação (ex.: câmera, multi-touch, ...);
as bibliotecas de API que precisam ser linkadas com a aplicação (ex.: Google Maps Library).
A primeira tarefa do arquivo manifest, é informar ao sistema os componentes, conforme exemplo abaixo.
No elemento <application>, o atributo android:icon identifica recursos para um ícone que será utilizado para a aplicação
No elemento <activity>, o atributo android:name especifica a qualificação completa do nome da subclasse Activity e o atributo android:label especifica uma string para um label visível da activity
Devem ser declarados todos os componentes, utilizando-se dos seguintes elementos:
<activity> para activities;
<service> para services;
<receiver> para broadcast receivers;
<provider> para content providers.
Activities, services e content providers que não forem declarados no arquivo manifest não serão visíveis ao sistema e, portanto, não poderão ser executados. Broadcast receivers poderão ser declarados no arquivo manifest, mas também poderão ser registrados dinamicamente através do método registerReceiver().
Para maiores informações, consultar o documento "The Android Manifest.xml File".
Exemplo do arquivo manifest:
<?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>
Uma atividade dos componentes Activity, Service ou BroadcastReceiver podem ser acionadas através de um Intent. Pode-se acionar o componente de forma explícita quando o nome da classe é utilizado ou implicitamente, descrevendo-se a o tipo de ação a ser executada e, opcionalmente, os dados que serão processados pelo componente. As ações que um componente pode executar devem ser declaradas no arquivo intent para que o sistema possa identificá-las. Quando existe mais de um componente que pode executar uma determinada ação, o sistema permite que o usuário selecione o componente que executará a ação.
ATENÇÃO: para acionar um Service, deve-se fazê-lo de forma explícita, pois não há como garantir o Service que será executado e não haverá como o usuário identificar a execução deste. Isto é considerada uma falha de segurança. A partir da versão 5.0 do Android (API nível 21), o sistema dispara uma excessão se for chamado um bindService() com um Intent implícito. Não faça declarações de açöes para serviços no arquivo manifest.
O sistema identifica os componentes que poderão ser executados através da comparação do Intent recebido com os intent filters declarados no arquivo manifest dos aplicativos instalados.
Quando é declarado um Activity, podem ser declaradas as ações que são executadas por esta adicionando-se elementos <intent-filter>.
Por exemplo, você pode criar uma aplicação que permita a redação de um e-mail, você deve declarar um intent-filter android.intent.action.SEND.
Se uma aplicação criar um Intent com a ação "ACTION_SEND" e passá-la através do método startActivity(), o sistema poderá executar a sua action.
Para mais informações sobre a declaração de capacidades de componentes, consulte o documento Intents and Intent Filters
Abaixo um exemplo da declaração de capacidades no arquivo intent:
<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>
Nem todos os dispositivos Android possuirão todos os requisitos necessários para a execução da sua aplicação, portanto você pode declarar no arquivo manifest quais são os requisitos obrigatórios de hardware e software. A maioria destes requisitos são apenas informativos e não serão lidos pelo sistema, porém as lojas de aplicativos poderão filtrar os aplicativos de acordo com os dispositivos suportados.
No exemplo abaixo, é feita a declaração de uma aplicação que irá necessitar de uma câmera e se utilizar de API lançadas junto ao Android 2.1 (API nível 7). Também é possível declarar se um componente é obrigatório ou não através do atributo "required=false":
Mais informações podem ser obtidas através de consulta ao documento Device Compatibility.
<manifest ... >
<uses-feature android:name="android.hardware.camera.any"
android:required="true" />
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" />
...
</manifest>
Uma aplicação Android é composta por recursos que vão além do código fonte. Todo recurso incluído no SDK gera um identificador numérico único que pode ser usado ao longo da aplicação.
É possível gerar variações do recurso para serem utilizadas de acordo com o tipo de aparelho, a língua, a orientação, dentre outros.
Para maiores informações, consultar o documento Providing Resources.
Para aprender sobre melhores práticas e desenvolvimento robusto, consultar o documento Guide to App Architeture.