Реализация библиотеки Java SDK

Платформа Android содержит большое количество общих библиотек Java, которые можно дополнительно включить в путь к классам приложений с помощью <uses-library> в манифесте приложения. Приложения связываются с этими библиотеками, поэтому относитесь к ним так же, как к остальной части Android API, с точки зрения совместимости, проверки API и поддержки инструментов. Обратите внимание, однако, что большинство библиотек не имеют этих функций.

Тип модуля java_sdk_library помогает управлять библиотеками такого типа. Производители устройств могут использовать этот механизм для своих собственных общих библиотек Java, чтобы обеспечить обратную совместимость своих API. Если производители устройств используют свои собственные общие библиотеки Java через <uses-library> вместо пути загрузочного класса, java_sdk_library может проверить, являются ли эти библиотеки Java стабильными для API.

java_sdk_library реализует необязательные API-интерфейсы SDK для использования приложениями. Библиотеки, реализованные через java_sdk_library в вашем файле сборки ( Android.bp ), выполняют следующие операции:

  • Создаются библиотеки заглушек, включающие stubs , stubs.system и stubs.test . Эти библиотеки-заглушки создаются путем распознавания @hide , @SystemApi и @TestApi .
  • java_sdk_library управляет файлами спецификаций API (такими как current.txt ) в подкаталоге API. Эти файлы проверяются на соответствие последнему коду, чтобы убедиться, что они являются самыми последними версиями. Если это не так, вы получите сообщение об ошибке, в котором объясняется, как их обновить. Вручную просмотрите все изменения обновлений, чтобы убедиться, что они соответствуют вашим ожиданиям.

    Чтобы обновить все API, используйте m update-api . Чтобы проверить актуальность API, используйте m checkapi .
  • Файлы спецификаций API сверяются с самыми последними опубликованными версиями Android, чтобы гарантировать обратную совместимость API с более ранними выпусками. Модули java_sdk_library , предоставляемые как часть AOSP, размещают свои ранее выпущенные версии в prebuilts/sdk/<latest number> .
  • Что касается проверок файлов спецификаций API, вы можете сделать одно из следующих трех действий:
    • Разрешите продолжить проверку. (Ничего не делай.)
    • Отключите проверки, добавив в java_sdk_library следующее:
      unsafe_ignore_missing_latest_api: true,
    • Предоставьте пустые API для новых модулей java_sdk_library , создав пустые текстовые файлы с именем module_name.txt в каталоге version/scope/api .
  • Если установлена ​​библиотека реализации для среды выполнения, создается и устанавливается XML-файл.

Как работает java_sdk_library

java_sdk_library именем X создает следующее:

  1. Две копии библиотеки реализации: одна библиотека с именем X и другая с именем X.impl . Библиотека X установлена ​​на устройстве. Библиотека X.impl существует только в том случае, если другим модулям требуется явный доступ к библиотеке реализации, например, для использования в тестировании. Обратите внимание, что явный доступ требуется редко.
  2. Области можно включать и отключать для настройки доступа. (Подобно модификаторам доступа к ключевым словам Java, публичная область обеспечивает широкий диапазон доступа; тестовая область содержит API-интерфейсы, используемые только при тестировании.) Для каждой включенной области библиотека создает следующее:
    • Исходный модуль заглушек (типа модуля droidstubs ) — использует исходный код реализации и выводит набор исходных кодов заглушек вместе с файлом спецификации API.
    • Библиотека заглушек (типа модуля java_library ) - это скомпилированная версия заглушек. Библиотеки, используемые для компиляции, отличаются от тех, что поставляются в java_sdk_library , что гарантирует, что детали реализации не просочатся в заглушки API.
    • Если вам нужны дополнительные библиотеки для компиляции заглушек, используйте свойства stub_only_libs и stub_only_static_libs для их предоставления.

Если java_sdk_library называется « X » и компилируется как « X », всегда обращайтесь к ней именно так и не изменяйте ее. Сборка выберет соответствующую библиотеку. Чтобы убедиться, что у вас есть наиболее подходящая библиотека, проверьте свои заглушки, чтобы убедиться, что сборка не привела к ошибкам. Внесите необходимые исправления, используя это руководство:

  • Убедитесь, что у вас есть подходящая библиотека, просмотрев командную строку и проверив, какие заглушки перечислены там, чтобы определить вашу область:
    • Область действия слишком широка: зависимой библиотеке требуется определенный объем API. Но вы видите API-интерфейсы, включенные в библиотеку, которые не входят в эту область, например системные API-интерфейсы, включенные в общедоступные API-интерфейсы.
    • Область действия слишком узкая: зависимая библиотека не имеет доступа ко всем необходимым библиотекам. Например, зависимая библиотека должна использовать системный API, но вместо этого получает общедоступный API. Обычно это приводит к ошибке компиляции, поскольку необходимые API-интерфейсы отсутствуют.
  • Чтобы исправить библиотеку, выполните только одно из следующих действий:
    • Измените sdk_version , чтобы выбрать нужную версию. ИЛИ ЖЕ
    • Явно укажите соответствующую библиотеку, например <X>.stubs или <X>.stubs.system .

Использование java_sdk_library X

Библиотека реализации X используется, когда на нее ссылаются из apex.java_libs . Однако из-за ограничения Soong, когда на библиотеку X ссылаются из другого модуля java_sdk_library в той же библиотеке APEX, необходимо явно использовать X.impl , а не библиотеку X .

Когда на java_sdk_library ссылаются из другого места, используется библиотека-заглушка. Библиотека заглушек выбирается в соответствии с настройкой свойства sdk_version соответствующего модуля. Например, модуль, указывающий sdk_version: "current" , использует общедоступные заглушки, тогда как модуль, указывающий sdk_version: "system_current" , использует системные заглушки. Если точное совпадение найти не удается, используется ближайшая библиотека-заглушка. java_sdk_library , которая предоставляет только общедоступный API, будет предоставлять общедоступные заглушки для всех.

Поток сборки с библиотекой Java SDK
Рис. 1. Поток сборки с библиотекой Java SDK

Примеры и источники

srcs и api_packages должны присутствовать в java_sdk_library .

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

AOSP рекомендует (но не требует), чтобы новые экземпляры java_sdk_library явно включали области API, которые они хотят использовать. Вы также можете (необязательно) перенести существующие экземпляры java_sdk_library , чтобы явно включить области API, которые они будут использовать:

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

Чтобы настроить библиотеку impl , используемую для среды выполнения, используйте все обычные свойства java_library , такие как hostdex , compile_dex и 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,
    }

Чтобы настроить библиотеки заглушек, используйте следующие свойства:

  • merge_annotations_dirs и merge_inclusion_annotations_dirs .
  • api_srcs : список необязательных исходных файлов, которые являются частью API, но не частью библиотеки времени выполнения.
  • stubs_only_libs : список библиотек Java, которые находятся в пути к классам при создании заглушек.
  • hidden_api_packages : список имен пакетов, которые должны быть скрыты от API.
  • droiddoc_options : Дополнительный аргумент для металавы .
  • droiddoc_option_files : список файлов, на которые можно ссылаться из droiddoc_options используя $(location <label>) , где <file> — запись в списке.
  • annotations_enabled .

java_sdk_library — это java_library , но он не является модулем droidstubs и поэтому не поддерживает все свойства droidstubs . Следующий пример был взят из файла сборки библиотеки 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,
    }

Сохранение обратной совместимости

Система сборки проверяет, поддерживают ли API обратную совместимость, сравнивая последние файлы API с сгенерированными файлами API во время сборки. java_sdk_library выполняет проверку совместимости, используя информацию, предоставленную prebuilt_apis . Все библиотеки, созданные с помощью java_sdk_library , должны иметь файлы API в последней версии api_dirs в prebuilt_apis . Когда вы выпускаете версию, API перечисляет файлы и библиотеки-заглушки, которые можно получить с помощью сборки dist с PRODUCT=sdk_phone_armv7-sdk .

Свойство api_dirs — это список каталогов версий API в prebuilt_apis . Каталоги версий API должны располагаться на уровне каталогов Android.bp .

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

Настройте каталоги со структурой version / scope /api/ в каталоге prebuilts. version соответствует уровню API, а scope определяет, является ли каталог общедоступным, системным или тестовым.

  • version / scope содержит библиотеки Java.
  • version / scope /api содержит файлы API .txt . Создайте здесь пустые текстовые файлы с именами module_name .txt и module_name -removed.txt .
     ├── 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