O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Visão geral da Play Feature Delivery

O modelo de exibição de apps do Google Play usa Android App Bundles para gerar e disponibilizar 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.

A Play Feature Delivery usa recursos avançados de pacotes de apps, permitindo que determinados recursos do app sejam enviados condicionalmente ou transferidos por download sob demanda.

Usar módulos de recursos para entrega personalizada

Um benefício exclusivo dos módulos de recursos é a capacidade de personalizar como e quando diferentes recursos do app são transferidos por download para dispositivos com o Android 5.0 (nível 21 da API) ou mais recente. 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 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 com módulos de recursos. Ou seja, os módulos de recursos 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 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 módulos de recursos e como elas podem ser usadas para otimizar o tamanho inicial do download 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 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 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 que o usuário não precisa mais, consulte Gerenciar módulos instalados.

Entrega sob demanda Permite que o app solicite módulos de recursos 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 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 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 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 e configure a entrega condicional.
Entrega instantânea O Google Play Instant permite que os usuários interajam com seu app sem instalar APKs no dispositivo. Eles podem 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. 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 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 é apenas o primeiro passo. Para oferecer compatibilidade com o Google Play Instant, o tamanho de download do módulo base do app e de um determinado recurso instantâneo precisa atender a restrições rígidas de tamanho. Para saber mais, leia Ativar experiências instantâneas reduzindo o tamanho do app ou jogo.

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 criar 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 de entrega de recursos: a modularização dos recursos do app como módulos de recursos é um requisito para aproveitar as opções de entrega personalizada da Play Feature Delivery, como as entregas sob demanda, condicional e instantânea. A criação de recursos sob demanda requer mais esforço e a possível refatoração do app. Por isso, analise atentamente quais recursos do app seriam mais beneficiados com a modularização em módulos de recursos 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 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, é possível modularizar gradativamente os recursos do app sem alterar o comportamento atual dele, configurando módulos de recursos para entrega na instalação.

Manifesto do módulo de recursos

Durante a criação de um novo módulo de recursos usando o Android Studio, o ambiente de desenvolvimento integrado inclui a maioria dos atributos de manifesto que o módulo precisa para se comportar como um módulo de recursos. Além disso, alguns atributos são injetados pelo sistema no 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.

Atributo Descrição
<manifest
...
Este é seu bloco <manifest> típico.
xmlns:dist="http://schemas.android.com/apk/distribution" Especifica um novo namespace XML dist:, que é descrito abaixo.
split="split_name" Quando o Android Studio cria 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 recurso usando o Android Studio, o ambiente de desenvolvimento integrado usa o que você especificou como o Nome do módulo para identificar o módulo como um subprojeto do Gradle no arquivo de configurações do Gradle.

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

android:isFeatureSplit="true | false"> Quando o Android Studio cria 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. 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 o app incluir um ou mais módulos de recursos instantâneos, você também precisará ativar o módulo base como um módulo instantâneo. Com o Android Studio 3.5 ou mais recente, o ambiente de desenvolvimento integrado faz isso quando você cria um módulo de recursos instantâneos.

Não é possível definir esse elemento XML como true ao mesmo tempo em que <dist:on-demand/> é definido. No entanto, ainda é possível solicitar downloads sob demanda dos seus módulos de recursos 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 módulos de recursos instantâneos do app e os instala junto do APK básico, por padrão.

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

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

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

<dist:delivery> Encapsula opções que personalizam a entrega do módulo, conforme mostrado abaixo. Lembre-se de que cada módulo de recurso precisa configurar apenas um tipo dessas opções de entrega personalizada.
<dist:install-time> Especifica que o módulo precisa estar disponível no momento da instalação. Esse é o comportamento padrão para módulos de recursos que não especificam outro tipo de opção de entrega personalizada.

Para saber mais sobre downloads na instalação, leia Configurar entrega na instalação.

Esse nó também pode especificar condições que limitam o módulo a dispositivos que atendem a determinados requisitos, como recursos do dispositivo, país do usuário ou nível mínimo da API. Para saber mais, leia Configurar entrega condicional.

<dist:removable value="true | false" />

Quando não definido ou definido como false, o bundletool combina os módulos de tempo de instalação no módulo base ao gerar APKs divididos do pacote. Como haverá menos APKs divididos por causa da combinação, essa configuração pode melhorar o desempenho do seu app.

Quando removable é definido como true: os módulos de tempo de instalação não são combinados no módulo base. Defina como true caso queira desinstalar módulos no futuro. No entanto, configurar muitos módulos para serem removíveis pode aumentar o tempo de instalação do aplicativo.

O valor padrão é false. Só é necessário definir esse valor no manifesto se você quiser desativar a fusão de um módulo de recurso.

Observação: esse recurso só está disponível ao usar o Plug-in do Android para Gradle 4.2 ou ao usar o bundletool v1.0 na linha de comando.

</dist:install-time>  
<dist:on-demand/> Especifica que o módulo deve estar disponível como um download sob demanda. Ou seja, o módulo não está disponível no momento da instalação, mas seu app pode solicitar o download mais tarde.

Para saber mais sobre downloads sob demanda, leia Configurar entrega sob demanda.

</dist:delivery>
<application
android:hasCode="true | false">
...
</application>
Se o módulo de recursos não gera arquivos DEX, ou seja, 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.
  2. Adicione o seguinte ao manifesto do seu módulo básico:
    
    <application
      android:hasCode="true"
      tools:replace="android:hasCode">
      ...
    </application>
    

Testar a Play Feature Delivery

A melhor maneira de testar a Play Feature Delivery é pela Google Play Store. Isso acontece porque muitos dos benefícios da Play Feature Delivery são usados para adiar a geração, a assinatura e a disponibilização de APKs otimizados para a Play Store. Portanto, independentemente de você simplesmente fazer upload de um pacote de apps ou configurar opções de entrega mais avançadas, use os seguintes métodos para testar o app.

  • Compartilhar o app com um URL. Essa é a maneira mais rápida de fazer upload do 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.

Criar um URI para um recurso

Se você quiser acessar um recurso armazenado em um módulo de recursos usando um URI, veja como gerar um URI de módulo de recursos usando Uri.Builder():

Kotlin

val uri = Uri.Builder()
                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
                .authority(context.getPackageName()) // Look up the resources in the application with its splits loaded
                .appendPath(resources.getResourceTypeName(resId))
                .appendPath(String.format("%s:%s",
                  resources.getResourcePackageName(resId), // Look up the dynamic resource in the split namespace.
                  resources.getResourceEntryName(resId)
                  ))
                .build()

Java

String uri = Uri.Builder()
                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
                .authority(context.getPackageName()) // Look up the resources in the application with its splits loaded
                .appendPath(resources.getResourceTypeName(resId))
                .appendPath(String.format("%s:%s",
                  resources.getResourcePackageName(resId), // Look up the dynamic resource in the split namespace.
                  resources.getResourceEntryName(resId)
                  ))
                .build().toString();

Cada parte do caminho para o recurso é construída no tempo de execução, garantindo que o namespace correto seja gerado após o carregamento dos APKs divididos.

Como exemplo de como o URI é gerado, suponha que você tenha um app e módulos de recursos com esses nomes:

  • Nome do pacote do app: com.example.my_app_package
  • Nome do pacote de recursos do elemento: com.example.my_app_package.my_dynamic_feature

Se o resId no snippet de código acima se referir a um recurso de arquivo bruto com o nome "my_video" no módulo de recursos, o código Uri.Builder() acima produzirá o seguinte:

android.resource://com.example.my_app_package/raw/com.example.my_app_package.my_dynamic_feature:my_video

Esse URI pode ser usado pelo seu app para acessar o recurso do módulo de recursos.

Para validar os caminhos no URI, use o APK Analyzer para inspecionar o APK do módulo de recursos e determinar o nome do pacote:

Uma captura de tela do APK Analyzer inspecionando o conteúdo de um arquivo de recurso compilado.

Figura 2. Use o APK Analyzer para inspecionar o nome do pacote em um arquivo de recurso compilado.

Considerações sobre módulos de recursos

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

  • Instalar 50 ou mais módulos de recursos em um único dispositivo pode levar a problemas de desempenho. Para evitar isso, use a biblioteca Play Core para desinstalar módulos de que o usuário não precisa mais.
  • Limite o número de módulos configurados como removíveis para entrega na instalação a 10 ou menos. Caso contrário, o tempo de download e instalação do app poderá aumentar.
  • Apenas dispositivos com o Android 5.0 (nível 21 da API) e versões mais recentes são compatíveis com download e instalação de recursos sob demanda. Para disponibilizar o recurso para versões anteriores do Android, ative a opção Fusing ao criar um módulo de recursos.
  • Para que o app tenha acesso aos módulos de recursos transferidos por download, ative a SplitCompat.
  • Se o tamanho do download do seu recurso for grande, o app precisará da confirmação do usuário antes de fazer o download desse módulo em um dispositivo.
  • Os módulos de recursos não podem especificar as 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 quando outro app tentar iniciar a atividade. Além disso, seu app precisa confirmar se um recurso 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 Play Feature Delivery requer que você publique seu aplicativo usando um pacote de apps, verifique se há problemas conhecidos com o pacote de apps.

Outros recursos

Para saber mais sobre como usar a Play Feature Delivery, use os recursos a seguir.

Amostras

Codelabs

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

Postagens do blog

Vídeos