Android Dev Summit, October 23-24: two days of technical content, directly from the Android team. Sign-up for livestream updates.

Sobre o Dynamic Delivery

O modelo de veiculação de app do Google Play, denominado Dynamic Delivery, usa Android App Bundles para gerar e veicular APKs otimizados para a configuração de dispositivo de cada usuário. Assim, os usuários fazem o download apenas do código e dos recursos necessários para executar o app. Não é mais necessário compilar, assinar e gerenciar vários APKs para oferecer compatibilidade com diferentes dispositivos. Além disso, os usuários contam com downloads menores e mais otimizados.

A maioria dos projetos de app não exige muito esforço para compilar pacotes de apps compatíveis com a veiculação de APKs divididos otimizados por meio do Dynamic Delivery. Por exemplo, se você já organiza o código e os recursos do app de acordo com as convenções estabelecidas, basta compilar Android App Bundles assinados usando o Android Studio ou a linha de comando e enviá-los para o Google Play. O Dynamic Delivery se torna um benefício automático.

Para oferecer compatibilidade com recursos avançados do Dynamic Delivery, por exemplo, a configuração de determinados recursos do app para serem entregues condicionalmente ou transferidos por download sob demanda, leia a seção sobre como personalizar a entrega de recursos.

Dynamic Delivery com APKs divididos

Um componente fundamental do Dynamic Delivery é o mecanismo de APK dividido disponível no Android 5.0 (API nível 21) e posteriores. Os APKs divididos são muito semelhantes aos APKs comuns: eles incluem bytecode DEX compilado, recursos e um manifesto do Android. No entanto, a plataforma Android pode tratar vários APKs divididos instalados como um único app. Ou seja, você pode instalar vários APKs divididos que têm acesso a códigos e recursos comuns e são exibidos como um app instalado no dispositivo.

A vantagem dos APKs divididos é a capacidade de dividir um APK monolítico, ou seja, um APK que inclui código e recursos para todos os elementos e configurações de dispositivos compatíveis com seu app, em pacotes menores e discretos instalados no dispositivo do usuário, conforme necessário.

Por exemplo, um APK dividido pode incluir o código e os recursos de outra funcionalidade de que apenas alguns dos seus usuários precisam, enquanto outro APK dividido inclui recursos apenas para um idioma ou densidade de tela específico. Cada APK dividido é transferido por download e instalado mediante a solicitação do usuário ou quando exigido pelo dispositivo.

O conteúdo a seguir descreve os diferentes tipos de APK que podem ser instalados juntos em um dispositivo para formar sua experiência completa com o app. Você saberá como configurar o projeto do seu app para oferecer compatibilidade com esses APKs nas próximas seções desta página.

  • APK básico: contém o código e os recursos que todos os outros APKs divididos podem acessar e oferece a funcionalidade básica para seu app. Quando um usuário solicita o download do seu app, esse APK é transferido por download e instalado primeiro. Isso ocorre porque somente o manifesto do APK básico contém uma declaração completa dos serviços, provedores de conteúdo, permissões, requisitos de versão da plataforma e dependências do app nos recursos do sistema. O Google Play gera o APK básico para seu app a partir do módulo de app (ou básico) do projeto. Se sua preocupação estiver relacionada com a redução do tamanho inicial de download do app, é importante lembrar que todo o código e os recursos incluídos neste módulo estão presentes no APK básico.
  • APKs de configuração: cada um desses APKs inclui bibliotecas nativas e recursos para uma densidade de tela, arquitetura de CPU ou idioma específicos. Quando o usuário faz o download do seu app, o dispositivo transfere e instala apenas os APKs de configuração destinados ao dispositivo. Cada APK de configuração é uma dependência de um APK básico ou de um APK de recursos dinâmicos. Ou seja, eles são transferidos por download e instalados juntamente com o APK a que disponibilizam código e recursos. Diferentemente dos módulos básicos e de recursos dinâmicos, você não cria um módulo separado para os APKs de configuração. Se você usa práticas padrão para organizar recursos alternativos e específicos da configuração para seus módulos básicos e de recursos dinâmicos, o Google Play gera automaticamente APKs de configuração para você.
  • APKs de recursos dinâmicos: cada um desses APKs contém código e recursos para uma funcionalidade do seu app que você modulariza usando módulos de recursos dinâmicos. Com o Dynamic Delivery, você pode personalizar como e quando esse recurso é transferido por download em um dispositivo. Por exemplo, usando a biblioteca Play Core, os APKs dinâmicos podem ser instalados sob demanda depois que o APK básico é instalado no dispositivo, para oferecer outras funcionalidades para o usuário. Imagine um app de chat que faz o download do recurso de captura e envio de fotos e o instala somente quando o usuário pede para usar essa funcionalidade. Como os recursos dinâmicos podem não estar disponíveis no momento da instalação, é importante incluir todos os códigos e recursos comuns no APK básico. Ou seja, o recurso dinâmico presumirá que somente o código e os recursos do APK básico estão disponíveis no momento da instalação. O Google Play gera APKs de recursos dinâmicos para o app com base nos módulos de recursos dinâmicos do projeto.

Imagine um app com três módulos de recursos dinâmicos e compatibilidade com várias configurações de dispositivo. A Figura 1 abaixo ilustra o que seria a árvore de dependências dos diversos APKs do app. Observe que o APK base forma o topo da árvore, e todos os outros APKs dependem do APK básico. Se você quiser saber como os módulos desses APKs são representados em um Android App Bundle, consulte Formato do Android App Bundle.

O APK básico está no topo da árvore, e todos os outros APKs de recursos dinâmicos dependem dele. APKs de configuração, que incluem código e recursos específicos da configuração do dispositivo para base e cada APK de recursos dinâmicos, formam os nós folhas da árvore de dependência.

Figura 1. Árvore de dependência de um app veiculado por meio de APKs divididos

Não é necessário compilar esses APKs por conta própria. O Google Play faz isso por você usando um único pacote de apps assinado que você compila com o Android Studio. Para saber mais sobre o formato do pacote de apps e como compilar um, consulte Compilar, implantar e fazer upload de Android App Bundles.

Dispositivos com Android 4.4 (API nível 19) e anteriores

Como os dispositivos com o Android 4.4 (API nível 19) e anteriores não são compatíveis com download e instalação de APKs divididos, o Google Play oferece a esses dispositivos um único APK, denominado multi-APK, otimizado para a configuração do dispositivo. Ou seja, os multi-APKs representam a experiência completa do seu app, mas não incluem código e recursos desnecessários, como aqueles para outras densidades de tela e arquiteturas de CPU.

No entanto, eles incluem recursos para todos os idiomas compatíveis com seu app. Isso permite, por exemplo, que o usuário altere a configuração de idioma preferencial do app sem precisar fazer o download de outro multi-APK.

Multi-APKs não têm a capacidade de fazer o download de módulos de recursos dinâmicos sob demanda posteriormente. Para incluir um módulo dinâmico nesse APK, você precisa desativar a opção On-demand ou ativar Fusing durante a criação do módulo de recursos dinâmicos.

Com o Dynamic Delivery, não é necessário compilar, assinar, fazer upload e gerenciar APKs para cada configuração de dispositivo compatível com seu app. Você ainda compila e faz upload de um único pacote de apps para todo o app, e o Google Play cuida do resto para você. Sendo assim, independentemente de você pretender ou não oferecer compatibilidade com dispositivos com o Android 4.4 ou anteriores, o Dynamic Delivery disponibiliza um mecanismo de veiculação flexível para você e seus usuários.

Modularizar o app

A modularização de apps é o processo de separação de componentes lógicos de um projeto de app em módulos discretos.

A reorganização da funcionalidade do app nesses componentes discretos exige atenção e tempo. No entanto, a modularização oferece os seguintes benefícios ao projeto:

  • Desenvolvimento paralelo: com a separação de componentes lógicos do seu app em módulos, diferentes equipes ou indivíduos da sua organização podem se apropriar de cada módulo e trabalhar neles com menos conflitos de mesclagem ou interrupções em outras equipes. Além disso, se você tiver lógica usada em várias partes do app, poderá usar módulos de biblioteca para promover a reutilização e o encapsulamento de código.
  • Melhoria no tempo de compilação: sistemas de compilação, como o Android Studio com o Gradle, são otimizados para projetos organizados em módulos. Por exemplo, se você ativa a otimização de execução de projetos paralelos do Gradle em uma estação de trabalho que inclui um processador de vários núcleos, o sistema de compilação pode compilar vários módulos ao mesmo tempo e reduzir significativamente os tempos de compilação. Quanto mais modular for seu projeto, mais significativa será a melhoria no desempenho da compilação.
  • Personalização da entrega de recursos: a modularização dos recursos do app como módulos de recursos dinâmicos é um requisito para aproveitar as opções de entrega personalizada do Dynamic Delivery, como as entregas sob demanda, condicional e instantânea. A criação de recursos dinâmicos sob demanda é mais trabalhosa e pode exigir a refatoração do app. Por isso, analise atentamente quais recursos do seu app seriam mais beneficiados com a modularização em recursos dinâmicos e com as opções de entrega personalizada.

É necessário atenção e tempo para que a modularização do seu projeto por recursos de app seja realizada corretamente. Quando você decidir começar a modularizar o app, configure primeiro o módulo básico com as propriedades necessárias para oferecer compatibilidade com recursos modulares. Em seguida, você pode modularizar gradativamente os recursos do app sem alterar o comportamento atual dele, configurando módulos de recursos dinâmicos para entrega na instalação.

Usar módulos de recursos dinâmicos para entrega personalizada

Uma vantagem exclusiva do Dynamic Delivery é a capacidade de personalizar como e quando diferentes recursos do app são transferidos por download para dispositivos com o Android 5.0 (API nível 21) ou posteriores. Por exemplo, para reduzir o tamanho inicial do download do app, configure determinados recursos para serem transferidos conforme necessário sob demanda ou apenas por dispositivos compatíveis com determinadas capacidades, como a de tirar fotos ou de oferecer compatibilidade com funcionalidades de realidade aumentada.

Embora você receba downloads altamente otimizados por padrão quando faz upload do app como um pacote de apps, as opções de entrega de recursos mais avançadas e personalizáveis exigem outras configurações e a modularização dos recursos do app por meio de módulos de recursos dinâmicos. Ou seja, os módulos de recursos dinâmicos oferecem os elementos básicos para a criação de recursos modulares que você pode configurar para cada download, conforme necessário.

Imagine um app que permite ao usuário comprar e vender mercadorias em um mercado on-line. Você pode modularizar cada uma das seguintes funcionalidades do app em módulos de recursos dinâmicos separados:

  • Login e criação da conta
  • Navegação no mercado
  • Disponibilização de itens para venda
  • Processamento de pagamentos

A tabela abaixo descreve as diferentes opções de entrega compatíveis com os módulos de recursos dinâmicos e como elas podem ser usadas para otimizar o tamanho do download inicial do app de amostra do mercado.

Opção de entrega Comportamento Exemplo de caso de uso Primeiros passos
Entrega na instalação Por padrão, os módulos de recursos dinâmicos que não configuram nenhuma das opções de entrega descritas acima são transferidos por download na instalação do app. Esse é um comportamento importante, porque significa que você pode adotar opções de entrega avançadas gradativamente. Por exemplo, você só pode usufruir da modularização dos recursos do seu app e ativar a entrega sob demanda depois de ter implementado totalmente os downloads sob demanda usando a biblioteca Play Core.

Além disso, o app pode solicitar a desinstalação de recursos posteriormente. Portanto, se você precisar de determinados recursos na instalação do app, mas não depois disso, poderá reduzir o tamanho da instalação, solicitando que o recurso seja removido do dispositivo.

Se o app tiver determinadas atividades de treinamento, como um guia interativo sobre como comprar e vender itens no mercado, você poderá incluir esse recurso na instalação do app, por padrão.

No entanto, para reduzir o tamanho de instalação, o app poderá solicitar a exclusão do recurso depois que o usuário concluir o treinamento.

Modularize seu app usando módulos de recursos dinâmicos que não configuram opções avançadas de entrega.

Para saber como reduzir o tamanho de instalação do app removendo determinados módulos de recursos dinâmicos de que o usuário não precisa mais, leia Gerenciar módulos instalados.

Entrega sob demanda Permite que o app solicite módulos de recursos dinâmicos e faça o download deles, conforme necessário. Se apenas 20% das pessoas que usam o app do mercado publicarem itens para venda, uma boa estratégia para reduzir o tamanho inicial do download para a maioria dos usuários é usar a funcionalidade para tirar fotos, incluir a descrição de um item e disponibilizar itens para venda na forma de um download sob demanda. Ou seja, você pode configurar o módulo de recursos dinâmicos para que a funcionalidade de venda do app seja transferida por download somente quando o usuário mostrar interesse em colocar itens à venda no mercado.

Além disso, se o usuário deixar de realizar vendas depois de um determinado período, o app poderá reduzir o tamanho da instalação solicitando a desinstalação do recurso.

Crie um módulo de recursos dinâmicos e configure a entrega sob demanda. Assim, o app poderá usar a biblioteca Play Core para solicitar o download do módulo sob demanda.
Entrega condicional Permite que você especifique determinados requisitos de dispositivos do usuário, como recursos de hardware, localidade e nível mínimo da API, para determinar se um recurso modularizado é transferido por download na instalação do app. Se o app do mercado tem alcance global, talvez seja necessário oferecer compatibilidade com formas de pagamento conhecidas apenas em regiões ou locais específicos. Para reduzir o tamanho inicial do download do app, você pode criar módulos de recursos dinâmicos separados para processar determinados tipos de forma de pagamento e instalá-los condicionalmente no dispositivo do usuário com base na localidade registrada dele. Crie um módulo de recursos dinâmicos e configure a entrega condicional.
Entrega instantânea O Google Play Instant permite que o usuário interaja com seu app sem instalar APKs no dispositivo. Em vez disso, ele pode conhecer seu app usando o botão "Testar agora" da Google Play Store ou um URL criado por você. Essa forma de entregar conteúdo facilita o aumento do engajamento com seu app.

Com a entrega instantânea, você pode usar o Google Play Instant para permitir que o usuário acesse determinados recursos do app instantaneamente, sem fazer a instalação.

Imagine um jogo que inclua as primeiras fases em um módulo leve de recursos dinâmicos. Ative esse módulo instantaneamente para que o usuário possa conhecer o jogo de imediato por meio de um link de URL ou do botão "Testar agora", sem instalar o app. Crie um módulo de recursos dinâmicos e configure a entrega instantânea. Assim, o app poderá usar a biblioteca Play Core para solicitar o download do módulo sob demanda.

A modularização dos recursos do app por meio de módulos de recursos dinâmicos é apenas o primeiro passo. Para oferecer compatibilidade com o Google Play Instant, o tamanho do download do módulo básico do app e um determinado recurso dinâmico instantâneo precisam cumprir restrições rígidas de tamanho. Para saber mais, leia Ativar experiências instantâneas reduzindo o tamanho do app ou do jogo.

Manifesto do módulo de recursos dinâmicos

Durante a criação de um novo módulo de recursos dinâmicos no Android Studio, o ambiente de desenvolvimento integrado inclui a maioria dos atributos de manifesto que o módulo exige para se comportar como um recurso dinâmico. Além disso, alguns atributos são injetados pelo sistema em tempo de compilação. Assim, você não precisa especificá-los nem modificá-los. A tabela a seguir descreve os atributos do manifesto que são importantes para os módulos de recursos dinâmicos.

Atributo Descrição
<manifest
...
Este é seu bloco <manifest> normal.
xmlns:dist="http://schemas.android.com/apk/distribution" Especifica um novo namespace XML dist:, que é descrito abaixo.
split="split_name" Quando o Android Studio compila seu pacote de apps, ele inclui esse atributo para você. Portanto, não inclua nem modifique esse atributo por conta própria.

Define o nome do módulo, que seu app especifica ao solicitar um módulo sob demanda usando a biblioteca Play Core.

Como o Gradle determina o valor deste atributo:

Por padrão, quando você cria um módulo de recursos dinâmicos usando o Android Studio, o ambiente de desenvolvimento integrado usa o que você especificou como o Module name, isto é, o nome do módulo, para identificar o módulo como um subprojeto do Gradle no arquivo de configurações do Gradle.

Quando você compila seu pacote de apps, o Gradle usa o último elemento do caminho do subprojeto para injetar esse atributo no manifesto do módulo. Por exemplo, se você criar um novo módulo de recursos dinâmicos no diretório MyAppProject/features/ e especificar "dynamic_feature1" como o Module name, o ambiente de desenvolvimento integrado adicionará ':features:dynamic_feature1' como um subprojeto no arquivo settings.gradle. Quando você compila seu pacote de apps, o Gradle injeta <manifest split="dynamic_feature1"> no manifesto do módulo.

android:isFeatureSplit="true | false"> Quando o Android Studio compila seu pacote de apps, ele inclui esse atributo para você. Portanto, não inclua nem modifique esse atributo manualmente.

Especifica que este é um módulo de recursos dinâmicos. Os manifestos no módulo básico e nos APKs de configuração omitem esse atributo ou o definem como false.

<dist:module Esse novo elemento XML define os atributos que determinam como o módulo é empacotado e distribuído como APKs.
dist:instant="true | false" Especifica se o módulo deve estar disponível por meio do Google Play Instant como uma experiência instantânea.

Se seu app incluir um ou mais módulos de recursos dinâmicos instantâneos, você também precisará ativar o módulo básico como instantâneo. Com o Android Studio 3.3 ou posterior, o ambiente de desenvolvimento integrado faz isso quando você cria um módulo de recursos dinâmicos instantâneo.

Não é possível definir esse elemento XML como true ao mesmo tempo em que define dist:onDemand="true". No entanto, você ainda pode solicitar downloads sob demanda dos seus recursos dinâmicos instantâneos como experiências instantâneas usando a biblioteca Play Core. Por padrão, quando o usuário faz o download do seu app e o instala, o dispositivo faz o download dos recursos dinâmicos instantâneos do app e os instala juntamente com o APK básico.

dist:onDemand="true | false" Especifica se o módulo deve estar disponível como um download sob demanda. Ou seja, se esse atributo for definido como true, o módulo não estará disponível no momento da instalação, mas o app poderá solicitar o download dele posteriormente.

Se esse atributo for definido como false, o módulo será incluído quando o usuário fizer o download do seu app pela primeira vez e instalá-lo.

Para saber mais sobre downloads sob demanda, consulte Fazer o download de módulos com a biblioteca Play Core.

dist:title="@string/feature_name" Especifica um título direcionado ao usuário para o módulo. Por exemplo, o dispositivo pode exibir esse título quando solicita uma confirmação de download.

Você precisa incluir o recurso de string para esse título no arquivo module_root/src/source_set/res/values/strings.xml do módulo básico.

<dist:fusing dist:include="true | false" />
</dist:module>
Especifica se o módulo deve ser incluído em multi-APKs destinados a dispositivos com o Android 4.4 (API nível 20) ou anteriores.

Além disso, quando você usa bundletool para gerar APKs a partir de um pacote de apps, apenas os módulos de recursos dinâmicos que definem essa propriedade como true são incluídos no APK universal. Esse APK é monolítico e inclui código e recursos para todas as configurações de dispositivo compatíveis com o app.

<application
android:hasCode="true | false">
...
</application>
Se o módulo de recursos dinâmicos não gera arquivos DEX, isto é, não contém nenhum código que seja compilado posteriormente no formato de arquivo DEX, você precisa fazer o seguinte (caso contrário, poderá receber erros de tempo de execução):
  1. Defina android:hasCode como "false" no manifesto do módulo de recursos dinâmicos.
  2. Adicione o seguinte ao manifesto do seu módulo básico:
    
        <application
          android:hasCode="true"
          tools:replace="android:hasCode">
          ...
        </application>
        

Testar o Dynamic Delivery

A melhor maneira de testar o Dynamic Delivery é por meio da Google Play Store. Isso acontece porque muitos dos benefícios do Dynamic Delivery contam com o adiamento da geração, assinatura e veiculação otimizadas do APK na Play Store. Sendo assim, tanto para incluir compatibilidade básica com o Dynamic Delivery fazendo upload de um pacote de apps como para configurar opções de entrega personalizada, use os seguintes métodos para testar seu app com o Dynamic Delivery:

  • Compartilhar o app com um URL: essa é a maneira mais rápida de fazer upload do seu pacote de apps e compartilhar seu app como um link da Google Play Store com trusted testers. Além disso, essa é a maneira mais rápida de testar opções de entrega personalizada, como o download de recursos sob demanda.
  • Configurar um teste aberto, fechado ou interno: esse método oferece canais de teste estruturados e é uma boa maneira de testar a versão final do seu app antes de lançá-lo para usuários externos.

Considerações sobre recursos dinâmicos

Se você quer publicar um app que inclui módulos de recursos dinâmicos para uma faixa de produção, lembre-se de que:

  • Apenas dispositivos com o Android 5.0 (API nível 21) e posteriores são compatíveis com download e instalação de recursos dinâmicos sob demanda. Para disponibilizar o recurso dinâmico para versões anteriores do Android, ative a opção Fusing ao criar um módulo de recursos dinâmicos.
  • Para que o app tenha acesso imediato aos módulos de recursos dinâmicos transferidos por download, ative a SplitCompat.
  • Se o tamanho do download do seu recurso dinâmico for grande, o app precisará da confirmação do usuário antes do download desse módulo em um dispositivo.
  • Os módulos de recursos dinâmicos não devem especificar atividades no manifesto com android:exported definido como true. Isso porque não há garantia de que o dispositivo tenha feito o download do módulo de recursos dinâmicos quando outro aplicativo tenta iniciar a atividade. Além disso, seu app deve confirmar se um recurso dinâmico foi transferido por download antes de tentar acessar o código e os recursos relacionados. Para saber mais, leia Gerenciar módulos instalados.
  • Como a entrega dinâmica exige que você publique o app usando um pacote de apps, verifique se já sabe quais são os problemas conhecidos do pacote de apps.

Outros recursos

Para saber mais sobre como usar o Dynamic Delivery compatível, use os recursos a seguir.

Amostras

  • Amostra da API PlayCore (link em inglês), que demonstra o uso da API PlayCore para solicitar recursos dinâmicos e fazer o download deles.
  • Amostra de carregamento de código dinâmico (link em inglês), que demonstra três abordagens diferentes para acessar com segurança o código a partir de um módulo de recursos dinâmicos instalado.

Codelabs

  • Seu primeiro Android App Bundle (link em inglês), um codelab que explora os princípios básicos de Android App Bundles e mostra como começar a compilar seu pacote de apps rapidamente usando o Android Studio. Esse codelab também analisa como testar seus pacotes de apps usando bundletool.
  • Módulos sob demanda (link em inglês), que ajuda a criar um app que faz o download de recursos dinâmicos sob demanda e os instala.

Postagens do blog

Vídeos