Criar uma biblioteca Android

Estruturalmente, uma biblioteca Android é igual a um módulo de app Android. Ela pode conter tudo o que é necessário para criar um app, inclusive código-fonte, arquivos de recursos e um manifesto do Android. No entanto, em vez de ser compilada em um APK para execução em um dispositivo, uma biblioteca Android é compilada em um arquivo ARchive do Android (AAR), que pode ser usado como dependência de um módulo de app Android. Ao contrário dos arquivos JAR, os arquivos AAR oferecem a seguinte funcionalidade para apps Android:

  • Os arquivos AAR podem conter recursos Android e um arquivo de manifesto, o que permite empacotar recursos compartilhados como layouts e drawables, além de classes e métodos Java.
  • Os arquivos AAR podem conter bibliotecas C/C++ para uso pelo código C/C++ do módulo do app.

Um módulo de biblioteca é útil nas seguintes situações:

  • Ao compilar vários apps que usam alguns componentes em comum, como atividades, serviços ou layouts de IU.
  • Ao compilar um app que existe em várias variações de APK, como uma versão gratuita e paga, e os mesmos componentes essenciais são necessários nas duas versões.

Nos dois casos, basta mover os arquivos que você quer reutilizar para um módulo de biblioteca e adicioná-la como dependência para cada módulo de app. Esta página ensina a proceder nas duas situações.

Criar um módulo de biblioteca

Para criar um novo módulo de biblioteca no projeto, faça o seguinte:

  1. Clique em File > New > New Module.
  2. Na janela Create New Module exibida, clique em Android Library e em Next.

    Existe também uma opção para criar uma biblioteca Java, que cria um arquivo JAR tradicional. Embora um arquivo JAR seja útil para muitos projetos e principalmente quando é necessário compartilhar código com outras plataformas, esse tipo de arquivo não permite a inclusão de recursos Android nem arquivos de manifesto, o que é muito útil para reutilização de código em projetos Android. Portanto, este guia se concentra na criação de bibliotecas Android.

  3. Atribua um nome à biblioteca, selecione uma versão mínima do SDK para o código na biblioteca e clique em Finish.

Após a conclusão da sincronização do projeto Gradle, o módulo de biblioteca será exibido no painel Project à esquerda. Se a pasta do novo módulo não for exibida, verifique se a janela está mostrando a visualização Android.

Converter um módulo de aplicativo em um módulo de biblioteca

Se você tiver um módulo de app com todo o código que quer reutilizar, poderá transformá-lo em um módulo de biblioteca da seguinte forma:

  1. Abra o arquivo de nível de módulo build.gradle.
  2. Exclua a linha do applicationId. Apenas um módulo de app para Android pode definir isso.
  3. Na parte superior do arquivo, você verá o seguinte:

    Groovy

    implementation project(path: ':example-library')
    

    Kotlin

      plugins {
          id("com.android.application")
      }
      

    Groovy

      apply plugin: 'com.android.application'

    Mude isso para:

    Groovy

      apply plugin: 'com.android.library'
      

    Kotlin

      plugins {
          id("com.android.library")
      }
      
  4. Salve o arquivo e clique em File > Sync Project with Gradle Files.

É isso. A estrutura inteira do módulo se mantém, mas ele passa a operar como uma biblioteca Android e o build criará um arquivo AAR em vez de APK.

Quando quiser criar um arquivo AAR, selecione o módulo da biblioteca na janela Project e clique em Build > Build APK.

Adicionar dependências com a caixa de diálogo Project Structure

Usar a biblioteca para o mesmo projeto

Para usar o código da nova biblioteca Android em outro módulo de app ou biblioteca no mesmo projeto, adicione uma dependência no projeto:

  1. Navegue até File > Project Structure > Dependencies.
  2. Selecione o módulo em que você usará a biblioteca.
  3. Na guia Declared Dependencies, clique em e selecione Module Dependency no menu suspenso.

  4. Na caixa de diálogo "Add Module Dependency", selecione o módulo da sua biblioteca.

    Adicionar dependência de módulo na caixa de diálogo Project Structure

  5. Selecione a configuração que exige essa dependência ou selecione "implementation" se ela se aplicar a todas as configurações e clique em OK.

O Studio editará o arquivo build.gradle dos módulos para adicionar a dependência do formulário:

Kotlin

implementation(project(path: ":example-library"))

Usar a biblioteca em outros projetos

A maneira recomendada de compartilhar dependências (JARs e AARs) é com um repositório Maven, hospedado em um serviço como o Maven Central (link em inglês) ou com uma estrutura de diretórios no disco local. Para mais informações sobre como usar os repositórios do Maven, consulte Repositórios remotos.

Quando uma biblioteca Android é publicada em um repositório Maven, os metadados são incluídos para que as dependências da biblioteca sejam incluídas no build consumido. Isso possibilita a eliminação automática da duplicação da biblioteca se ela for usada em vários lugares.

Para usar o código de uma biblioteca Android em outro módulo de app, faça o seguinte:

  1. Navegue até File > Project Structure > Dependencies.
  2. Na guia Declared Dependencies, clique em e selecione Library Dependency no menu suspenso.

  3. Na caixa de diálogo Add Library Dependency, use a caixa de pesquisa para encontrar a biblioteca a ser adicionada. Este formulário pesquisa os repositórios especificados nos arquivos de compilação do projeto no bloco repositories.

    Adicionar dependência da biblioteca na caixa de diálogo Project Structure

  4. Selecione a configuração que exige essa dependência ou selecione "implementação" se ela se aplicar a todas as configurações.

  5. Confira o arquivo build.gradle do seu app para confirmar uma declaração parecida com a seguinte, dependendo da configuração do build selecionada:

    implementation 'com.example:examplelibrary:1.0.0'

Adicionar AAR ou JAR como uma dependência

Para usar o código de uma biblioteca Android em outro módulo de app, faça o seguinte:

  1. Navegue até File > Project Structure > Dependencies.
  2. Na guia Declared Dependencies, clique em e selecione Jar Dependency no menu suspenso.

  3. Na caixa de diálogo Add Jar/Aar Dependency, primeiro insira o caminho para o arquivo .aar ou .jar. Em seguida, selecione a configuração a que a dependência se aplica. Se a biblioteca estiver disponível para todas as configurações, selecione "implementation".

    Adicionar dependências AAR na caixa de diálogo Project Structure

  4. Confira o arquivo build.gradle do seu app para confirmar uma declaração parecida com a seguinte, dependendo da configuração do build selecionada:

      implementation files('my_path/my_lib.aar')
    

Como alternativa, se você estiver executando os builds do Gradle fora do Android Studio, pode importar uma dependência adicionando um caminho para ela no arquivo build.gradle do app. Exemplo:

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
    ...
}

Para ver mais informações sobre como adicionar dependências do Gradle, consulte Adicionar dependências de compilação.

Escolher os recursos que serão públicos

Por padrão, todos os recursos de uma biblioteca são públicos. Para tornar todos os recursos implicitamente privados, é necessário definir pelo menos um atributo específico como público. Os recursos incluem todos os arquivos do diretório res/ do projeto, como imagens. Para evitar que os usuários da biblioteca acessem recursos destinados exclusivamente para uso interno, use esse mecanismo automático de designação de privacidade declarando um ou mais recursos públicos. Como alternativa, faça com que todos os recursos sejam privados adicionando uma tag <public /> vazia, que não marca nada como público e torna todos os recursos privados.

Para declarar um recurso público, adicione uma declaração <public> ao arquivo public.xml da biblioteca. Se você não tiver adicionado recursos públicos antes, será necessário criar o arquivo public.xml no diretório res/values/ da biblioteca.

O código de exemplo a seguir cria dois recursos públicos de string com os nomes mylib_app_name e mylib_public_string:

<resources>
    <public name="mylib_app_name" type="string"/>
    <public name="mylib_public_string" type="string"/>
</resources>

Torne públicos todos os recursos que você quer que fiquem visíveis para os desenvolvedores que usam a biblioteca.

Além de evitar que os usuários da biblioteca vejam sugestões de preenchimento de código dos recursos internos da biblioteca, os atributos implicitamente privados também permitem renomear ou remover recursos particulares sem afetar os clientes da biblioteca. Os recursos privados são filtrados no preenchimento de código, e o Lint emite um alerta quando você tenta fazer uma referência a um recurso privado.

Ao criar uma biblioteca, o Plug-in do Android para Gradle extrai as definições de recursos públicos para o arquivo public.txt, que, depois disso, é empacotado dentro do arquivo AAR.

Considerações de desenvolvimento de módulos de biblioteca

Esteja ciente dos comportamentos e limitações abaixo ao desenvolver módulos de biblioteca e apps dependentes.

Depois de adicionar referências a módulos de biblioteca ao módulo do app Android, você pode definir a prioridade relativa. No tempo de compilação, as bibliotecas são mescladas com o app, uma de cada vez, começando pela biblioteca de menor prioridade até a de maior prioridade.

  • Conflitos de mesclagem de recursos

    As ferramentas de compilação mesclam recursos de um módulo de biblioteca com os de um módulo de app dependente. Se um determinado código de recurso for definido nos dois módulos, o recurso do app será usado.

    Se ocorrerem conflitos entre várias bibliotecas AAR, será usado o recurso da biblioteca listada primeiro na lista de dependências (perto da parte superior do bloco dependencies).

    Para evitar conflitos de recursos para códigos de recursos comuns, considere usar um prefixo ou outro esquema de nomenclatura consistente exclusivo para o módulo, ou exclusivo em todos os módulos do projeto.

  • Em versões multimódulo, as dependências JAR são tratadas como dependências transitivas

    Quando você adiciona uma dependência JAR a um projeto de biblioteca que gera um AAR, o JAR é processado pelo módulo da biblioteca e empacotado com o AAR correspondente.

    No entanto, se seu projeto incluir um módulo de biblioteca consumado por um módulo de app, o módulo de app tratará a dependência JAR local de biblioteca como uma dependência transitiva. Nesse caso, o JAR local será processado pelo app do módulo que consumi-lo e não pelo módulo da biblioteca. Isso é feito para builds compilações incrementais que são causados por alterações no código da biblioteca.

    Qualquer conflito de recursos Java causado por dependências JAR locais precisa ser resolvido no módulo do app que consome a biblioteca.

  • Um módulo de biblioteca pode depender de uma biblioteca JAR externa

    É possível desenvolver um módulo de biblioteca que depende de uma biblioteca externa Por exemplo, a biblioteca externa do Maps. Nesse caso, o app dependente precisa ser criado em um destino que inclua a biblioteca externa (por exemplo, o complemento Google APIs). Observe também que o módulo de biblioteca e o app dependente precisam declarar a biblioteca externa em um elemento <uses-library> dos arquivos de manifesto deles.

  • O atributo minSdkVersion do módulo do app precisa ser igual ou maior que a versão definida pela biblioteca

    Uma biblioteca é compilada como parte do módulo do app dependente, portanto, as APIs usadas no módulo da biblioteca precisam ser compatíveis com a versão de plataforma compatível com o módulo do app.

  • Cada módulo de biblioteca cria a própria classe R

    Ao criar os módulos de apps dependentes, os módulos de biblioteca são compilados em um arquivo AAR, que é adicionado ao módulo do app. Portanto, cada biblioteca tem a própria classe R, nomeada de acordo com o nome do pacote da biblioteca. A classe R gerada a partir do módulo principal e do módulo de biblioteca é criada em todos os pacotes necessários, incluindo o pacote do módulo principal e os pacotes das bibliotecas.

  • Um módulo de biblioteca pode incluir um arquivo de configuração do ProGuard próprio

    Se você tiver um projeto de biblioteca usado para compilar e publicar um AAR, você poderá adicionar um arquivo de configuração do ProGuard à configuração de build da biblioteca e o plug-in Android Gradle aplicará as regras do ProGuard especificadas. As ferramentas de criação incorporam esse arquivo no arquivo AAR gerado para o módulo de biblioteca. Ao adicionar a biblioteca a um módulo de app, o arquivo ProGuard da biblioteca é anexado ao arquivo de configuração do ProGuard (proguard.txt) do módulo do app.

    A incorporação de um arquivo ProGuard no módulo de biblioteca garante que os módulos de apps que dependem da biblioteca não precisem atualizar manualmente os próprios arquivos ProGuard para usar a biblioteca. Quando o sistema de compilação do Android Studio cria o app, ele usa as diretivas do módulo do app e da biblioteca. Portanto, não é necessário executar um redutor de código na biblioteca em uma etapa separada.

    Para adicionar as regras do ProGuard ao seu projeto de biblioteca, especifique o nome do arquivo com a propriedade consumerProguardFiles dentro do bloco defaultConfig do arquivo build.gradle da biblioteca. Por exemplo, o snippet a seguir define lib-proguard-rules.txt como o arquivo de configuração ProGuard da biblioteca:

    Groovy

    android {
        defaultConfig {
            consumerProguardFiles 'lib-proguard-rules.txt'
        }
        ...
    }

    Kotlin

    android {
        defaultConfig {
            consumerProguardFiles("lib-proguard-rules.txt")
        }
        ...
    }

    No entanto, se o módulo da sua biblioteca fizer parte de um build multimódulo compilado em um APK e não gerar um arquivo AAR, execute a redução de código apenas no módulo de app que consome a biblioteca. Para saber mais sobre as regras do ProGuard e o uso delas, leia Reduzir, ofuscar e otimizar o app.

  • Testar um módulo de biblioteca é o mesmo que testar um app

    A principal diferença é que a biblioteca e as dependências dela são incluídas automaticamente como dependências do APK de teste. Isso quer dizer que o APK de teste não inclui apenas o próprio código, mas também o AAR da biblioteca e todas as dependências correspondentes. Como não há um "app em teste" separado, a tarefa androidTest instala (e desinstala) apenas o APK de teste.

    Ao mesclar vários arquivos de manifesto, o Gradle segue a ordem de prioridade padrão e mescla o manifesto da biblioteca com o manifesto principal do APK de teste.

Anatomia de um arquivo AAR

A extensão de um arquivo AAR é .aar, e o tipo de artefato Maven também precisa ser aar. O arquivo em si é um arquivo ZIP. A única entrada obrigatória é /AndroidManifest.xml.

Além disso, um arquivo AAR pode incluir uma ou mais destas entradas opcionais: