lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

Fundamentos de aplicativos

Os aplicativos do Android são programados em linguagem de programação Java. As ferramentas do Android SDK compilam o código — em conjunto com todos os arquivos de dados e recursos — em um APK — um pacote Android, que é um arquivo de sufixo .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 na própria sandbox:

  • O sistema operacional Android é um sistema Linux multiusuário em que cada aplicativo é um usuário diferente.
  • Por padrão, o sistema atribui a cada aplicativo um ID de usuário do Linux exclusivo (o ID é usado somente pelo sistema e é desconhecido para o aplicativo). O sistema define permissões para todos os arquivos em um aplicativo, de modo que somente o ID de usuário atribuído àquele aplicativo pode acessá-los.
  • Cada processo tem a própria máquina virtual (VM), portanto, o código de um aplicativo é executado isoladamente de outros aplicativos.
  • Por padrão, cada aplicativo é executado no próprio processo do Linux. O Android inicia o processo quando é preciso executar algum componente do aplicativo; em seguida, encerra-o quando não mais é necessário ou quando o sistema precisa recuperar memória para outros aplicativos.

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:

  • É possível fazer com que dois aplicativos compartilhem o mesmo ID de usuário do Linux, caso em que eles são capazes de acessar os arquivos um do outro. Para preservar os recursos do sistema, os aplicativos com o mesmo ID de usuário também podem ser combinados para serem executados no mesmo processo Linux e compartilharem a mesma VM (também é preciso atribuir o mesmo certificado aos aplicativos).
  • Um aplicativo pode solicitar permissão para acessar dados de dispositivo como contatos do usuário, mensagens SMS, o sistema montável (cartão SD), câmera, Bluetooth etc. O usuário precisa conceder essas permissões de forma explícita. Para saber mais, consulte Trabalho com permissões 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:

  • Componentes fundamentais de estrutura que definem o aplicativo.
  • O arquivo de manifesto em que são declarados os componentes e os recursos de dispositivo necessários ao aplicativo.
  • Recursos separados do código do aplicativo que permitem otimizar o comportamento de uma variedade de configurações de dispositivo.

Componentes de aplicativo

Componentes de aplicativo são os blocos de construção de um aplicativo Android. Cada componente é um ponto diferente pelo qual o sistema pode entrar em seu 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 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.

Eis os quatro tipos de componentes de aplicativos:

Atividades
Atividades representam uma tela única com uma interface do usuário. Por exemplo, um aplicativo de e-mail pode ter uma atividade que mostra uma lista de novos e-mails, outra atividade que compõe um e-mail e outra ainda que lê e-mails. Embora essas atividades funcionem juntas para formar uma experiência de usuário coesa no aplicativo de e-mail, elas são independentes entre si. Portanto, um aplicativo diferente pode iniciar qualquer uma dessas atividades (se o aplicativo de e-mails permitir). Por exemplo, um aplicativo de câmera pode iniciar a atividade no aplicativo de e-mail que compõe o novo e-mail para que o usuário compartilhe uma foto.

Uma atividade é implementada como uma subclasse de Activity — saiba mais sobre isso no guia do desenvolvedor Atividades.

Serviços
Serviços são componentes executados em segundo plano para realizar operações de execução longa ou para realizar trabalho para processos remotos. Eles não apresentam uma interface do usuário. Por exemplo, um serviço pode tocar música em segundo plano enquanto o usuário está em um aplicativo diferente ou buscar dados na rede sem bloquear a interação do usuário com uma atividade. Outro componente, como uma atividade, pode iniciar o serviço e deixá-lo executar ou vincular-se a ele para interagir.

Um serviço é implementado como uma subclasse de Service — saiba mais sobre isso no guia do desenvolvedor Serviços.

Provedores de conteúdo
Provedores de conteúdo gerenciam um conjunto compartilhado de dados do aplicativo. É possível armazenar os dados no sistema de arquivos, em um banco de dados SQLite ou em qualquer local de armazenamento persistente que o aplicativo possa acessar. Por meio do provedor de conteúdo, outros aplicativos podem consultar ou até modificar os dados (se o provedor de conteúdo permitir). Por exemplo, o sistema Android oferece um provedor de conteúdo que gerencia os dados de contato do usuário. Assim, qualquer aplicativo com as permissões adequadas pode consultar parte do provedor de conteúdo (como ContactsContract.Data) para ler e gravar informações sobre uma pessoa específica.

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 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.

Receptores de transmissão
Receptores de transmissão são componentes que respondem a anúncios de transmissão por todo o sistema. Muitas transmissões se originam do sistema — por exemplo, uma transmissão que anuncia que uma tela foi desligada, a bateria está baixa ou uma tela foi capturada. Os aplicativos também podem iniciar transmissões — por exemplo, para comunicar a outros dispositivos que alguns dados foram baixados no dispositivo e estão disponíveis para uso. Embora os receptores de transmissão não exibam nenhuma interface do usuário, eles podem criar uma notificação na barra de status para alertar ao usuário quando ocorre uma transmissão. Mais comumente, no entanto, um receptor de transmissão é somente um "portal" para outros componentes e realiza uma quantidade mínima de trabalho. Por exemplo, ele pode iniciar um serviço para executar um trabalho baseado no evento.

Os receptores de transmissão são implementados como subclasses de BroadcastReceiver e cada transmissão é entregue como um objeto Intent. Para obter mais informações, consulte a classe 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 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 nenhum ponto de entrada único (não há a função 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 de outro aplicativo. No entanto, o sistema Android pode fazer isso. Portanto, para ativar um componente em outro aplicativo, é preciso enviar uma mensagem ao sistema que especifique o intent de iniciar um componente específico. Em seguida, o sistema ativa o componente.

Ativação de componentes

Três dos quatro tipos de componente — atividades, serviços e receptores de transmissão — são ativados por uma mensagem assíncrona chamada intent. Os intents 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.

O intent é criada com um objeto Intent, que define uma mensagem para ativar um componente específico ou um tipo específico de componente — os intents podem ser explícitos ou implícitos, respectivamente.

Para atividades e serviços, os intents 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, um intent 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 Intent (por exemplo, é possível emitir um intent para que o usuário selecione um contato pessoal e retorne-o a você — o intent de retorno contém uma URI que aponta para o contato selecionado).

Para receptores de transmissão, o intent 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 intents. Em vez disso, ele é ativado por uma solicitação de um ContentResolver. O resolvedor de conteúdo trata 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 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 para ativar cada tipo de componente:

Para obter mais informações sobre intents, consulte o documento Intents e filtros de intents. Veja mais informações sobre a ativação de componentes específicos nos seguintes documentos: Atividades, Serviços, BroadcastReceiver e Provedores de Conteúdo.

O arquivo de manifesto

Antes de o sistema Android iniciar um componente de aplicativo, é preciso ler o arquivo AndroidManifest.xml (o arquivo de “manifesto”) do aplicativo para que o sistema saiba que 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:

  • Identifica todas as permissões do usuário de que o aplicativo precisa, como acesso à internet ou acesso somente leitura aos contatos do usuário.
  • Declara o nível de API mínimo exigido pelo aplicativo com base nas APIs que o aplicativo usa.
  • Declara os recursos de hardware e software usados ou exigidos pelo aplicativo, como câmera, serviços de Bluetooth ou tela multitoque.
  • As bibliotecas de API às quais o aplicativo precisa se vincular (outras além das APIs de estrutura do Android), como a biblioteca Google Maps.
  • E outros.

Declaração de componentes

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 android:icon aponta para recursos de um ícone que identifica o aplicativo.

No elemento <activity>, o atributo android:name especifica o nome da classe totalmente qualificada da subclasse de Activity e o atributo android:label especifica uma string a usar como rótulo da atividade visível ao usuário.

É preciso declarar todos os componentes desta forma:

Atividades, 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 BroadcastReceiver) e registrados no sistema chamando-se registerReceiver().

Para obter mais informações sobre a estrutura do arquivo de manifesto de aplicativos, consulte a documentação O arquivo AndroidManifest.xml.

Declaração de recursos de componentes

Conforme abordado acima, em Ativação de componentes, é possível usar uma 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) no intent. No entanto, a verdadeira força dos intents reside no conceito de intents implícitos. Os intents implícitos 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 pelo intent, o usuário selecionará qual deles usar.

Para o sistema identificar os componentes que podem responder a um intent, compara-se o intent recebido com os filtros de intent fornecidos no arquivo de manifesto de outros aplicativos no dispositivo.

Ao declarar uma atividade no manifesto do aplicativo, pode-se incluir filtros de intents que declarem os recursos da atividade para que ela responda a intents de outros aplicativos. Para declarar um filtro de intents no componentes, adiciona-se um elemento <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, poderá declarar um filtro de intents para responder a intents "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 um intent com a ação ACTION_SEND e passá-la para 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 intents, consulte o documento Intents e filtros de intents.

Declaração de requisitos do aplicativo

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 de 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 à 2.1 não poderão instalar o aplicativo 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 required como "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.

Recursos do aplicativo

Os aplicativos Android são compostos de mais que somente códigos — eles exigem 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, você deve 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 logo.png (salvo no diretório res/drawable/), as ferramentas de SDK gerarão um código de recurso chamado 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 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 do 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.

Continue lendo sobre:

Intents e filtros de intents
Informações sobre o uso de APIs Intent para ativar componentes de aplicativos, como atividades e serviços, e como disponibilizar componentes de aplicativo para uso em outros aplicativos.
Atividades
Informações sobre a criação de uma instância da classe Activity, que permite uma tela diferente no aplicativo com uma interface do usuário.
Fornecimento de recursos
Informações sobre a estrutura de aplicativos Android para recursos de aplicativo separados do código-fonte , inclusive como fornecer recursos alternativos para configurações de dispositivo específicas.

Você também pode se interessar por:

Compatibilidade do dispositivo
Informações sobre como o Android funciona em diferentes tipos de dispositivo e uma introdução a como otimizar o aplicativo para cada dispositivo ou restringir a disponibilidade a diferentes dispositivos.
Permissões do sistema
Informações sobre como o aplicativo restringe o acesso do Android a determinadas APIs sem um sistema de permissão que exija o consentimento do usuário para que o aplicativo use essas APIs.