Implementar biblioteca Java SDK

A plataforma Android contém um grande número de bibliotecas Java compartilhadas que podem ser opcionalmente incluídas no caminho de classe dos aplicativos com a tag <uses-library> no manifesto do aplicativo. Os aplicativos são vinculados a essas bibliotecas, portanto, trate-os como o restante da API do Android em termos de compatibilidade, revisão de API e suporte de ferramentas. Observe, entretanto, que a maioria das bibliotecas não possui esses recursos.

O tipo de módulo java_sdk_library ajuda a gerenciar bibliotecas desse tipo. Os fabricantes de dispositivos podem usar esse mecanismo para suas próprias bibliotecas Java compartilhadas, para manter a compatibilidade com versões anteriores de suas APIs. Se os fabricantes de dispositivos usarem suas próprias bibliotecas Java compartilhadas por meio da tag <uses-library> em vez do caminho bootclass, java_sdk_library poderá verificar se essas bibliotecas Java são estáveis ​​em termos de API.

A java_sdk_library implementa APIs SDK opcionais para uso por aplicativos. Bibliotecas implementadas por meio de java_sdk_library em seu arquivo de compilação ( Android.bp ) realizam as seguintes operações:

  • As bibliotecas de stubs são geradas para incluir stubs , stubs.system e stubs.test . Essas bibliotecas de stubs são criadas reconhecendo as anotações @hide , @SystemApi e @TestApi .
  • A java_sdk_library gerencia arquivos de especificação de API (como current.txt ) em um subdiretório de API. Esses arquivos são verificados em relação ao código mais recente para garantir que sejam as versões mais atuais. Caso contrário, você receberá uma mensagem de erro explicando como atualizá-los. Revise manualmente todas as alterações de atualização para garantir que elas correspondam às suas expectativas.

    Para atualizar todas as APIs, use m update-api . Para verificar se uma API está atualizada, use m checkapi .
  • Os arquivos de especificação da API são verificados em relação às versões do Android publicadas mais recentemente para garantir que a API seja compatível com versões anteriores. Os módulos java_sdk_library fornecidos como parte do AOSP colocam suas versões lançadas anteriormente em prebuilts/sdk/<latest number> .
  • Com relação às verificações dos arquivos de especificação da API, você pode fazer uma das três coisas a seguir:
    • Permita que as verificações prossigam. (Não faça nada.)
    • Desative as verificações adicionando o seguinte a java_sdk_library :
      unsafe_ignore_missing_latest_api: true,
    • Forneça APIs vazias para novos módulos java_sdk_library criando arquivos de texto vazios denominados module_name.txt no diretório version/scope/api .
  • Se a biblioteca de implementação do tempo de execução estiver instalada, um arquivo XML será gerado e instalado.

Como funciona java_sdk_library

Uma java_sdk_library chamada X cria o seguinte:

  1. Duas cópias da biblioteca de implementação: uma biblioteca chamada X e outra chamada X.impl . A Biblioteca X está instalada no dispositivo. A biblioteca X.impl existe apenas se o acesso explícito à biblioteca de implementação for necessário para outros módulos, como para uso em testes. Observe que o acesso explícito raramente é necessário.
  2. Os escopos podem ser ativados e desativados para personalizar o acesso. (Semelhante aos modificadores de acesso por palavra-chave Java, um escopo público fornece uma ampla variedade de acesso; um escopo de teste contém APIs usadas apenas em testes.) Para cada escopo habilitado, a biblioteca cria o seguinte:
    • Um módulo de origem stubs (do tipo de módulo droidstubs ) - consome a fonte de implementação e gera um conjunto de fontes stub junto com o arquivo de especificação da API.
    • Uma biblioteca de stubs (do tipo de módulo java_library ) - é a versão compilada dos stubs. As bibliotecas usadas para compilar isso não são as mesmas fornecidas para java_sdk_library , o que garante que os detalhes da implementação não vazem para os stubs da API.
    • Se você precisar de bibliotecas adicionais para compilar os stubs, use as propriedades stub_only_libs e stub_only_static_libs para fornecê-las.

Se uma java_sdk_library for chamada “ X ”, e estiver sendo compilada como “ X ”, sempre consulte-a dessa forma e não a modifique. A compilação selecionará uma biblioteca apropriada. Para garantir que você tenha a biblioteca mais apropriada, inspecione seus stubs para ver se a compilação introduziu erros. Faça as correções necessárias usando esta orientação:

  • Verifique se você tem uma biblioteca apropriada olhando na linha de comando e inspecionando quais stubs estão listados lá para determinar seu escopo:
    • O escopo é muito amplo: a biblioteca dependente precisa de um certo escopo de APIs. Mas você vê APIs incluídas na biblioteca que estão fora desse escopo, como APIs de sistema incluídas nas APIs públicas.
    • O escopo é muito restrito: a biblioteca dependente não tem acesso a todas as bibliotecas necessárias. Por exemplo, a biblioteca dependente precisa usar a API do sistema, mas em vez disso obtém a API pública. Isso geralmente resulta em um erro de compilação porque faltam as APIs necessárias.
  • Para corrigir a biblioteca, execute apenas um dos seguintes procedimentos:
    • Altere sdk_version para selecionar a versão necessária. OU
    • Especifique explicitamente a biblioteca apropriada, como <X>.stubs ou <X>.stubs.system .

uso de java_sdk_library X

A biblioteca de implementação X é usada quando é referenciada em apex.java_libs . No entanto, devido a uma limitação do Soong, quando a biblioteca X é referenciada de outro módulo java_sdk_library dentro da mesma biblioteca APEX, X.impl deve ser usado explicitamente , e não a biblioteca X .

Quando java_sdk_library é referenciado de outro lugar, uma biblioteca stubs é usada. A biblioteca stubs é selecionada de acordo com a configuração da propriedade sdk_version do módulo dependente. Por exemplo, um módulo que especifica sdk_version: "current" usa os stubs públicos, enquanto um módulo que especifica sdk_version: "system_current" usa os stubs do sistema. Se uma correspondência exata não puder ser encontrada, a biblioteca stub mais próxima será usada. Uma java_sdk_library que fornece apenas uma API pública fornecerá stubs públicos para todos.

Crie fluxo com a biblioteca Java SDK
Figura 1. Fluxo de construção com biblioteca Java SDK

Exemplos e fontes

As propriedades srcs e api_packages devem estar presentes em java_sdk_library .

java_sdk_library {
        name: "com.android.future.usb.accessory",
        srcs: ["src/**/*.java"],
        api_packages: ["com.android.future.usb"],
    }

O AOSP recomenda (mas não exige) que as novas instâncias java_sdk_library habilitem explicitamente os escopos de API que desejam usar. Você também pode (opcionalmente) migrar instâncias java_sdk_library existentes para ativar explicitamente os escopos de API que usarão:

java_sdk_library {
         name: "lib",
         public: {
           enabled: true,
         },
         system: {
           enabled: true,
         },
         …
    }

Para configurar a biblioteca impl usada para tempo de execução, use todas as propriedades java_library normais, como hostdex , compile_dex e errorprone .

java_sdk_library {
        name: "android.test.base",

        srcs: ["src/**/*.java"],

        errorprone: {
          javacflags: ["-Xep:DepAnn:ERROR"],
        },

        hostdex: true,

        api_packages: [
            "android.test",
            "android.test.suitebuilder.annotation",
            "com.android.internal.util",
            "junit.framework",
        ],

        compile_dex: true,
    }

Para configurar bibliotecas de stubs, use as seguintes propriedades:

  • merge_annotations_dirs e merge_inclusion_annotations_dirs .
  • api_srcs : a lista de arquivos de origem opcionais que fazem parte da API, mas não fazem parte da biblioteca de tempo de execução.
  • stubs_only_libs : A lista de bibliotecas Java que estão no caminho de classe ao construir stubs.
  • hidden_api_packages : a lista de nomes de pacotes que devem ser ocultados da API.
  • droiddoc_options : Argumento adicional para metalava .
  • droiddoc_option_files : lista os arquivos que podem ser referenciados em droiddoc_options usando $(location <label>) , onde <file> é uma entrada na lista.
  • annotations_enabled .

O java_sdk_library é um java_library , mas não é um módulo droidstubs e, portanto, não suporta todas as propriedades droidstubs . O exemplo a seguir foi retirado do arquivo de compilação da biblioteca android.test.mock .

java_sdk_library {
        name: "android.test.mock",

        srcs: [":android-test-mock-sources"],
        api_srcs: [
            // Note: The following aren’t APIs of this library. Only APIs under the
            // android.test.mock package are taken. These do provide private APIs
            // to which android.test.mock APIs reference. These classes are present
            // in source code form to access necessary comments that disappear when
            // the classes are compiled into a Jar library.
            ":framework-core-sources-for-test-mock",
            ":framework_native_aidl",
        ],

        libs: [
            "framework",
            "framework-annotations-lib",
            "app-compat-annotations",
            "Unsupportedappusage",
        ],

        api_packages: [
            "android.test.mock",
        ],
        permitted_packages: [
            "android.test.mock",
        ],
        compile_dex: true,
        default_to_stubs: true,
    }

Manter compatibilidade com versões anteriores

O sistema de compilação verifica se as APIs mantiveram compatibilidade com versões anteriores comparando os arquivos de API mais recentes com os arquivos de API gerados no momento da compilação. A java_sdk_library realiza a verificação de compatibilidade usando as informações fornecidas por prebuilt_apis . Todas as bibliotecas construídas com java_sdk_library devem ter arquivos API na versão mais recente de api_dirs em prebuilt_apis . Quando você lança a versão, a API lista arquivos e bibliotecas de stubs que podem ser obtidas com dist build com PRODUCT=sdk_phone_armv7-sdk .

A propriedade api_dirs é uma lista de diretórios de versões da API em prebuilt_apis . Os diretórios da versão API devem estar localizados no nível do diretório Android.bp .

prebuilt_apis {
       name: "foo",
       api_dirs: [
           "1",
           "2",
             ....
           "30",
           "current",
       ],
    }

Configure os diretórios com a estrutura version / scope /api/ no diretório prebuilts. version corresponde ao nível da API e scope define se o diretório é público, sistema ou teste.

  • version / scope contém bibliotecas Java.
  • version / scope /api contém arquivos .txt da API. Crie arquivos de texto vazios chamados module_name .txt e module_name -removed.txt aqui.
     ├── 30
          │   ├── public
          │   │   ├── api
          │   │   │   ├── android.test.mock-removed.txt
          │   │   │   └── android.test.mock.txt
          │   │   └── android.test.mock.jar
          │   ├── system
          │   │   ├── api
          │   │   │   ├── android.test.mock-removed.txt
          │   │   │   └── android.test.mock.txt
          │   │   └── android.test.mock.jar
          │   └── test
          │       ├── api
          │       │   ├── android.test.mock-removed.txt
          │       │   └── android.test.mock.txt
          │       └── android.test.mock.jar
          └── Android.bp