Este guia aborda as práticas e a arquitetura recomendadas para a criação de apps robustos com alta qualidade de produção.
Experiências dos usuários de apps para dispositivos móveis
Em geral, um app Android contém vários componentes de app, incluindo atividades, fragmentos, serviços, provedores de conteúdo e broadcast receivers. A maioria desses componentes de app é declarada no manifesto do app. O SO Android usa esse arquivo para decidir como integrar o app à experiência geral do usuário do dispositivo. Como um app Android comum pode conter vários componentes e os usuários geralmente interagem com vários apps em um curto período, os apps precisam se adaptar a diferentes tipos de fluxos de trabalho e tarefas direcionados ao usuário.
Os recursos de dispositivos móveis são limitados, então o sistema operacional pode interromper alguns processos de apps a qualquer momento para dar espaço a outros novos.
Considerando as condições desse ambiente, é possível que os componentes do app sejam iniciados individualmente e fora de ordem, e eles podem ser destruídos a qualquer momento pelo usuário ou pelo sistema operacional. Como esses eventos não estão sob seu controle, não armazene nem mantenha na memória dados ou estados de apps para os componentes do seu app, e não permita que os componentes dele dependam uns dos outros.
Princípios de arquitetura comuns
Se não é recomendável usar componentes do app para armazenar dados e estados, qual é a melhor forma de criar um app?
Conforme os apps para Android aumentam de tamanho, é importante definir uma arquitetura que permita o escalonamento, aumente a robustez e facilite o teste do app.
Uma arquitetura de app define os limites entre as partes do app e as responsabilidades de cada uma. A fim de atender às necessidades mencionadas acima, crie a arquitetura do app para seguir alguns princípios específicos.
Separação de conceitos
O princípio mais importante que precisa ser seguido é a separação de
conceitos (link em inglês).
É um erro comum escrever todo o código em uma
Activity
ou um
Fragment
. Essas classes baseadas em interface precisam
conter apenas a lógica que processa as interações entre a interface e o sistema operacional. Ao manter
essas classes o mais enxutas possível, você pode evitar muitos problemas relacionados ao
ciclo de vida de componentes e melhorar a capacidade de teste dessas classes.
Vale lembrar que a propriedade de implementações da Activity
e do Fragment
não é sua.
Na verdade, elas são apenas classes que representam o contrato entre o
SO Android e o app. O SO pode destruí-las a qualquer momento com base nas interações
do usuário ou devido a condições do sistema, como pouca memória. Para fornecer uma
experiência do usuário satisfatória e uma experiência de manutenção de app mais gerenciável,
o melhor é minimizar sua dependência dessas classes.
interface do Drive com base em modelos de dados
Outro princípio importante é que você precisa basear sua interface em modelos de dados, de preferência, modelos persistentes. Os modelos de dados representam os dados de um app. Eles são independentes dos elementos da interface e outros componentes do app. Isso significa que eles não estão vinculados ao ciclo de vida do componente da interface e do app, mas ainda vão ser destruídos quando o SO decidir remover o processo do app da memória.
Os modelos persistentes são ideais por estes motivos:
Seus usuários não perderão dados se o SO Android destruir o app para liberar recursos.
O app continuará a funcionar caso uma conexão de rede esteja instável ou indisponível.
Se você basear a arquitetura do app em classes de modelo de dados, ele vai se tornar mais testável e robusto.
Única fonte de informações
Quando um novo tipo de dado é definido no seu app, você precisa atribuir uma Única fonte de informações (SSOT, na sigla em inglês) a ele. A SSOT é a proprietária desses dados, e apenas ela pode fazer mudanças neles. Para isso, ela expõe os dados usando um tipo imutável, e para fazer mudanças ela expõe funções ou recebe eventos que outros tipos podem chamar.
Esse padrão traz vários benefícios:
- Ele centraliza todas as mudanças de um tipo específico de dados em um só lugar.
- Ele protege os dados para que outros tipos não possam fazer adulterações neles.
- Ele faz com que as mudanças nos dados sejam mais rastreáveis. Assim, os bugs são mais fáceis de detectar.
Em um aplicativo que prioriza o modo off-line, a fonte da verdade para os dados do aplicativo geralmente é um banco de dados. Em alguns outros casos, ela pode ser um ViewModel ou até mesmo a interface.
Fluxo de dados unidirecional
O princípio da Única fonte de informações geralmente é usado nos nossos guias com o padrão Fluxo de dados unidirecional (UDF, na sigla em inglês). No UDF, o estado flui em apenas uma direção. São os eventos que modificam o fluxo de dados na direção oposta.
No Android, o estado ou os dados geralmente fluem dos tipos de escopo mais altos da hierarquia para os mais baixos. Os eventos geralmente são acionados pelos tipos de escopo mais baixos até alcançarem a SSOT para o tipo de dados correspondente. Por exemplo, os dados do app geralmente fluem das fontes de dados para a interface. Já os eventos do usuário, como pressionamento de botões, fluem da interface para a SSOT, em que os dados do aplicativo são modificados e expostos em um tipo imutável.
Esse padrão garante melhor a consistência dos dados, é menos propenso a erros, é mais fácil de depurar e traz todos os benefícios do padrão SSOT.
Arquitetura de app recomendada
Esta seção demonstra como estruturar o app seguindo as práticas recomendadas.
Considerando os princípios de arquitetura comuns mencionados na seção anterior, cada aplicativo precisa ter pelo menos duas camadas:
- A camada de IU que mostra os dados do aplicativo na tela.
- A camada de dados que contém a lógica de negócios do app e expõe os dados do aplicativo.
É possível adicionar uma camada extra conhecida como camada de domínios para simplificar e reutilizar as interações entre a IU e as camadas de dados.

Arquitetura moderna de apps
Esta Arquitetura moderna de apps incentiva o uso das seguintes técnicas, entre outras:
- Uma arquitetura reativa e em camadas.
- Fluxo de dados unidirecional (UDF, na sigla em inglês) em todas as camadas do app.
- Uma camada da interface com detentores de estado para gerenciar a complexidade dela.
- Corrotinas e fluxos.
- Práticas recomendadas para injeção de dependência.
Para mais informações, consulte as seções a seguir, as outras páginas de arquitetura no índice e a página de recomendações, que contém um resumo das práticas mais importantes.
Camada de interface
A função da camada de IU (ou camada de apresentação) é exibir os dados do aplicativo na tela. Sempre que os dados mudam, seja devido à interação do usuário, como o pressionamento de um botão, ou a uma entrada externa, como uma resposta de rede, a interface é atualizada para refletir as mudanças.
A camada de IU é composta por dois itens:
- Elementos da IU que renderizam os dados na tela. Esses elementos são criados usando funções de visualizações ou do Jetpack Compose.
- Holders de estado, como classes ViewModel, que armazenam dados, os expõem à IU e processam a lógica.

Para saber mais sobre essa camada, consulte a página sobre a camada de IU.
Camada de dados
A camada de dados de um app contém a lógica de negócios. A lógica de negócios é o que agrega valor ao app. Ela é composta por regras que determinam como o app cria, armazena e muda dados.
A camada de dados é composta por repositórios que podem conter de zero a muitas
fontes de dados. Crie uma classe de repositório para cada tipo diferente de
dados processados no seu app. Por exemplo, você pode criar uma classe MoviesRepository
para dados relacionados a filmes ou uma classe PaymentsRepository
para dados
relacionados a pagamentos.

As classes de repositório são responsáveis por estas tarefas:
- Expor dados ao restante do app.
- Centralizar mudanças nos dados.
- Resolver conflitos entre várias fontes de dados.
- Abstrair fontes de dados do restante do app.
- Conter uma lógica de negócios.
Cada classe de origem de dados deve ser responsável por trabalhar com apenas uma origem, que pode ser um arquivo, uma rede ou um banco de dados local. As classes de fonte de dados são a ponte entre o aplicativo e o sistema para operações de dados.
Para saber mais sobre essa camada, consulte a página sobre a camadas de dados.
Camada de domínios
A camada de domínios é opcional e fica entre a interface e as camadas de dados.
A camada de domínios é responsável por encapsular a lógica de negócios complexa ou simples que é reutilizada por vários ViewModels. Essa camada é opcional, porque nem todos os apps vão ter esses requisitos. Use-a apenas quando necessário, por exemplo, para lidar com a complexidade ou favorecer a reutilização.

As classes nessa camada normalmente são chamadas de casos de uso ou interagentes. Cada caso
de uso precisa ser responsável por uma única funcionalidade. Por exemplo, o
app pode ter uma classe GetTimeZoneUseCase
se vários ViewModels dependerem de fusos horários
para mostrar a mensagem adequada na tela.
Para saber mais sobre essa camada, consulte a página da camada de domínios.
Gerenciar dependências entre componentes
As classes no app dependem de outras para funcionar corretamente. É possível usar um dos padrões de design abaixo para reunir as dependências de uma classe específica:
- Injeção de dependência (DI, na sigla em inglês): permite que as classes definam as próprias dependências sem as construir. Durante a execução, outra classe é responsável por fornecer essas dependências.
- Localizador de serviço (link em inglês): esse padrão traz um registro de onde as classes podem buscar, em vez de construir, as próprias dependências.
Esses padrões permitem dimensionar o código, porque fornecem padrões claros para gerenciar dependências sem duplicar o código ou elevar a complexidade dele. Além disso, permitem alternar rapidamente entre implementações de teste e de produção.
Recomendamos seguir os padrões de injeção de dependência e usar a biblioteca Hilt em apps Android. A biblioteca Hilt constrói os objetos automaticamente percorrendo a árvore de dependências, além de oferecer garantias de tempo de compilação nas dependências e criar contêineres de dependência para classes do framework do Android.
Práticas recomendadas gerais
A programação é um campo criativo, e a criação de apps Android não é uma exceção. Há muitas maneiras de resolver um problema: é possível comunicar dados entre várias atividades ou fragmentos, extrair dados remotos e os armazenar localmente no modo off-line ou lidar com qualquer outro cenário comum que apps não triviais encontrem.
Embora as recomendações abaixo não sejam obrigatórias, na maioria dos casos a observação delas torna sua base de código mais robusta, testável e de fácil manutenção a longo prazo:
Não armazene dados em componentes do app.
Evite designar os pontos de entrada do app, como atividades, serviços e broadcast receivers, como fontes de dados. Em vez disso, eles precisam se coordenar com outros componentes apenas para extrair o subconjunto de dados relevante para esse ponto de entrada. Cada componente do app tem vida curta, dependendo da interação do usuário com o dispositivo e da integridade geral do sistema.
Reduza as dependências nas classes do Android.
Os componentes do app precisam ser as únicas classes que dependem das APIs do SDK
do framework do Android, como Context
ou
Toast
. Abstrair outras classes delas no
app melhora a capacidade de teste e reduz o
acoplamento
no app.
Crie limites de responsabilidade bem definidos entre os vários módulos do app.
Por exemplo, não divulgue o código que carrega dados da rede em várias classes ou pacotes na sua base de código. Da mesma forma, não defina várias responsabilidades não relacionadas, como armazenamento de dados em cache e vinculação de dados, na mesma classe. Seguir a arquitetura de apps recomendada vai ajudar com isso.
Exponha o mínimo possível de cada módulo.
Por exemplo, não crie um atalho que exponha um detalhe de implementação interna de um módulo. Você pode economizar um pouco de tempo a curto prazo, mas provavelmente vai pagar caro por isso tecnicamente à medida que sua base do código progredir.
Concentre-se no núcleo exclusivo do seu app para que ele se destaque de outros.
Não reinvente a roda escrevendo o mesmo código boilerplate várias vezes. Em vez disso, concentre seu tempo e energia no que torna seu app único e deixe que as bibliotecas do Jetpack e outras bibliotecas recomendadas processem o boilerplate repetitivo.
Considere como tornar cada parte do app testável de forma isolada.
Por exemplo, ter uma API bem definida para buscar dados da rede facilita os testes do módulo que mantém esses dados em um banco de dados local. Se, em vez disso, você mesclar a lógica desses dois módulos em um só lugar ou distribuir o código de rede por toda a base de código, vai ser muito mais difícil, ou até impossível, testá-los.
Os tipos são responsáveis pela própria política de simultaneidade.
Se um tipo estiver executando um trabalho de bloqueio de longa duração, ele precisará ser responsável por mover esse cálculo para a linha de execução correta. Esse tipo específico sabe o tipo de cálculo que está sendo feito e em qual linha de execução ele precisa ser executado. Os tipos precisam ser protegidos, ou seja, eles podem ser chamados com segurança da linha de execução principal sem que ela seja bloqueada.
Aplique o máximo de persistência possível em dados relevantes e atualizados.
Dessa forma, os usuários podem aproveitar a funcionalidade do app mesmo quando o dispositivo estiver no modo off-line. Lembre-se de que nem todos os usuários têm conectividade constante e de alta velocidade e, mesmo se tiverem, eles podem ter sinal ruim em alguns lugares lotados.
Benefícios da arquitetura
Ter uma boa arquitetura implementada no app oferece muitos benefícios para as equipes de projetos e engenharia:
- Melhor manutenção, qualidade e robustez para o app em geral.
- Possibilidade de escalonamento do app. Mais pessoas e equipes podem contribuir para a mesma base de código com conflitos mínimos.
- Ajuda na integração. Como a arquitetura traz consistência ao projeto, os novos membros da equipe podem começar a trabalhar mais rápido e ser mais eficientes em menos tempo.
- Mais fácil de testar. Uma boa arquitetura incentiva tipos mais simples, que geralmente são mais fáceis de testar.
- Os bugs podem ser investigados metodicamente com processos bem definidos.
Investir na arquitetura também tem um impacto direto nos usuários. Eles se beneficiam de um aplicativo mais estável e com mais recursos graças a uma equipe de engenharia mais produtiva. No entanto, a arquitetura também exige um investimento inicial de tempo. Para justificar esse tempo para sua empresa, confira estes estudos de caso em que outras empresas compartilham as histórias de sucesso delas sobre as vantagens de ter uma boa arquitetura no app.
Exemplos
Os exemplos do Google abaixo demonstram uma boa arquitetura de apps. Acesse-os para ver a orientação na prática:
A Microsoft permite que pessoas e organizações trabalhem, aprendam, organizem, se conectem e criem usando seus principais apps do Microsoft 365. Para conseguir isso, ela sabe que é essencial oferecer uma experiência de produtividade ideal para os clientes em todos os dispositivos que eles usam. A Square ajuda milhões de vendedores a administrar seus negócios, desde o processamento seguro de cartões de crédito até soluções de ponto de venda e a configuração de uma loja on-line sem custo financeiro. A Square está migrando para a interface O Twitter é uma das redes sociais mais amplamente usadas.
plataformas de mídia em que os usuários podem ver o que está acontecendo no mundo a qualquer momento
momento. A equipe de engenharia começou a usar o Jetpack Compose para modernizar o
sistema O Monzo é um banco e um app que oferece
serviços financeiros digitais. A missão dele é fazer o dinheiro funcionar
para todos. o sistema de design do Monzo começou a se desviar do Material Design e,
ela queria uma maneira fácil de escrever e manter A Cuvva está melhorando os seguros radicalmente
oferecendo uma maneira realmente flexível de gerenciar a cobertura, tudo pelo seu smartphone.
Os engenheiros do Android da Cuvva passaram um tempo reestruturando o app.
e decidiu adotar um fluxo de ShareChat is a leading social media platform in India that allows users to share their opinions, document their lives, and make new friends in their native language. The standard Red Up Green Down color scheme that many wealth management app users take for granted can be very problematic for colorblind users and those with color vision deficiency.The Futubull team is embracing users’ needs by making concrete improvements so that everyone can grasp the key to wealth. TikTok, the world’s community-driven entertainment destination, brings over 1 billion people together from around the world to discover, create and share content they love. OkCredit is a credit account management app for millions of shop owners and their customers in India. With 140M transactions month over month, and 50M+ downloads, last year alone saw OkCredit recording $50 billion worth of transactions on the app. Operating at such a huge scale scale, OkCredit created a smooth and seamless experience for all their users by focusing on reducing ANRs and improving the app startup time. Lyft is committed to app excellence. They have to be. For a rideshare app — providing a vital, time-sensitive service to millions of drivers and riders every day — a slow or unresponsive app adds unacceptable friction. Josh is a short-video app from India, launched in 2020. One of the fastest growing short-video apps with over 124 million MAUs, optimizing it across a range of devices (high, mid, low end) and maintaining a standard experience across all of them is critical for their success. Improving app startups time and making the app responsive helped them achieve success. Microsoft Lens increases developer productivity using CameraX Zomato is an Indian multinational restaurant aggregator and food delivery company serving customers across 500 cities in India alone. In order to launch new features on their Android app, Headspace spent 8 months refactoring their architecture and rewriting in Kotlin. Learn how this reboot helped their business grow. Google Photos is the home for your memories, and their development team believes people should be able to enjoy those memories across all devices. Learn how Duolingo made the business decision to focus on Android performance and how they improved developer productivity and scaled their business. Mercari allows millions of people to shop and sell almost anything. The company was founded in 2013 in Japan, and it now is the largest smartphone-focused C2C marketplace in Japan. Google Duo is a simple, high quality video calling app for everyone. With the increase of people being at home during the Covid-19 pandemic, the Duo team saw a significant increase in people using the app to stay connected with friends & family, school and work. Headspace drive business growth by investing in Android app quality. SmartNews helps millions of people discover their world everyday by sharing timely news from a diverse set of news sources. Twitter is one of the most widely used social media platforms where users can see what’s happening in the world at any given moment. Delight Room Alarmy is an alarm app that can be turned off only when the pre-selected activities, such as taking a photo, solving a math problem, shaking phone, etc., are performed by the user. The Google Home app helps set up, manage, and control your Google Home, Google Nest, and Chromecast devices—plus thousands of connected home products like lights, cameras, thermostats, and more. Truecaller is an app that offers caller identification, call blocking, chat messaging and organized inbox. The app has a basic offering and a premium version which is ad-free and has a variety of unlocked features like advanced spam blocking and call recording.Microsoft Outlook, Teams e Office aumentaram o número de usuários ativos e a retenção com telas grandes
A Square aumenta a produtividade com o Compose
Twitter tem aumento na eficiência e velocidade dos desenvolvedores com o Compose
O Monzo cria um app mais robusto e de maior qualidade com o Compose
O Cuvva cria mais rápido e com maior qualidade com o Compose
ShareChat addresses Jank issues to increase feed scrolling by 60%
The Key to Wealth for Everyone
TikTok Optimizes User Experience with Android Tools
OkCredit’s average merchant transaction goes up by 30% after reducing ANR
Lyft improves Android app startup time for drivers by 21%
Josh sees increased customer retention by improving app startup time by 30%
Microsoft Lens increases developer productivity using CameraX
Increasing app speed by 30%: a key ingredient in Zomato’s growth recipe
Headspace's Android reboot increases monthly active users by 15%
Google Photos increased daily active users by building for large screens
Duolingo refactors on Android with MVVM and Jetpack libraries
Mercari improves UI development productivity by 56% with Jetpack Compose
Google Duo sees increased engagement and improved ratings by optimizing for larger screens
Headspace drive business growth by investing in Android app quality
SmartNews reduces lines of code by 20% and improves team morale with Kotlin
Twitter increases developer productivity and code reliability with Kotlin
Delight Room increased 90% of its organic US users with Play Console
Google Home reduces #1 cause of crashes by 33%
Truecaller brings ~40% subscribers back with real time developer notifications
Nenhuma recomendação no momento.
Tente fazer login na sua Conta do Google.