Ограничения на интерфейсы, отличные от SDK

Начиная с Android 9 (уровень API 28) платформа ограничивает, какие интерфейсы, не относящиеся к SDK, может использовать ваше приложение. Эти ограничения применяются всякий раз, когда приложение ссылается на интерфейс, не относящийся к SDK, или пытается получить его дескриптор с помощью отражения или JNI. Эти ограничения были введены, чтобы помочь улучшить опыт пользователя и разработчика и снизить риски сбоев для пользователей и экстренных развертываний для разработчиков. Для получения дополнительной информации об этом решении см. раздел Улучшение стабильности путем сокращения использования интерфейсов, не относящихся к SDK .

Различия между интерфейсами SDK и не-SDK

Вообще говоря, публичные интерфейсы SDK — это те, которые задокументированы в индексе пакетов Android framework. Обработка интерфейсов, не относящихся к SDK, — это деталь реализации, которую API абстрагирует, поэтому эти интерфейсы могут быть изменены без предварительного уведомления.

Чтобы избежать сбоев и неожиданного поведения, приложения должны использовать только официально задокументированные части классов в SDK. Это также означает, что вы не должны получать доступ к методам или полям, которые не перечислены в SDK, когда вы взаимодействуете с классом с использованием таких механизмов, как отражение.

Списки API не-SDK

С каждым выпуском Android ограничиваются дополнительные интерфейсы, не относящиеся к SDK. Мы знаем, что эти ограничения могут повлиять на ваш рабочий процесс выпуска, и мы хотим убедиться, что у вас есть инструменты для обнаружения использования интерфейсов, не относящихся к SDK, возможность дать нам отзыв и время для планирования и адаптации к новым политикам.

Чтобы минимизировать влияние ограничений, не относящихся к SDK, на ваш рабочий процесс разработки, интерфейсы, не относящиеся к SDK, разделены на списки, которые определяют, насколько строго ограничено их использование, в зависимости от того, какой уровень API является целевым. В следующей таблице описывается каждый из этих списков:

Список Кодовые теги Описание
Черный список
  • blocked
  • Устаревшее: blacklist
Интерфейсы, не входящие в SDK, которые вы не можете использовать независимо от целевого уровня API вашего приложения. Если ваше приложение попытается получить доступ к одному из этих интерфейсов, система выдаст ошибку .
Условно заблокирован
  • max-target-x
  • Устаревший: greylist-max-x

Начиная с Android 9 (уровень API 28) каждый уровень API имеет интерфейсы, не относящиеся к SDK, которые ограничиваются, когда приложение нацелено на этот уровень API.

Эти списки помечены максимальным уровнем API ( max-target-x ), на который приложение может ориентироваться, прежде чем приложение больше не сможет получать доступ к интерфейсам не-SDK в этом списке. Например, интерфейс не-SDK, который не был заблокирован в Android Pie, но теперь заблокирован в Android 10, является частью списка max-target-p ( greylist-max-p ), где «p» означает Pie или Android 9 (уровень API 28).

Если ваше приложение пытается получить доступ к интерфейсу, который ограничен для вашего целевого уровня API, система ведет себя так, как будто API является частью черного списка .

Неподдерживаемый
  • unsupported
  • Устаревший: greylist
Интерфейсы, не относящиеся к SDK, которые не ограничены и могут использоваться вашим приложением. Однако обратите внимание, что эти интерфейсы не поддерживаются и могут быть изменены без уведомления. Ожидайте, что эти интерфейсы будут условно заблокированы в будущих версиях Android в списке max-target-x .
SDK
  • Оба public-api и sdk
  • Устаревшие: как public-api , так и whitelist
Интерфейсы, которые можно свободно использовать и которые теперь поддерживаются как часть официально документированного индекса пакетов Android.
Тестовые API
  • test-api
Интерфейсы, которые используются для внутреннего тестирования системы, такие как API, которые облегчают тестирование через Compatibility Test Suite (CTS). Тестовые API не являются частью SDK. Начиная с Android 11 (API уровня 30) , тестовые API включены в черный список, поэтому приложениям не разрешено использовать их независимо от целевого уровня API. Все тестовые API не поддерживаются и могут быть изменены без предварительного уведомления, независимо от уровня API платформы.

Хотя вы можете использовать некоторые интерфейсы, не относящиеся к SDK (в зависимости от целевого уровня API вашего приложения), использование любого метода или поля, не относящегося к SDK, всегда несет высокий риск поломки вашего приложения. Если ваше приложение использует интерфейсы, не относящиеся к SDK, вам следует начать планировать миграцию на интерфейсы SDK или другие альтернативы. Если вы не можете найти альтернативу использованию интерфейса, не относящегося к SDK, для функции в вашем приложении, вам следует запросить новый публичный API .

Определите, к какому списку принадлежит интерфейс

Списки интерфейсов, не входящих в SDK, создаются как часть платформы. Информацию о каждом выпуске Android см. в следующих разделах.

Андроид 16

Для Android 16 (уровень API 36) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: 9102af02fe6ab68b92464bdff5e5b09f3bd62c65d1130aaf85d3296f17d38074

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 16 см. в разделе Обновления ограничений интерфейса, не входящего в SDK, в Android 16 .

Андроид 15

Для Android 15 (уровень API 35) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: 40134e205e58922a708c453726b279a296e6a1f34a988abd90cec0f3432ea5a9

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 15 см. в разделе Обновления ограничений интерфейса, не входящего в SDK, в Android 15 .

Андроид 14

Для Android 14 (уровень API 34) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: 7e00db074cbe51c51ff4b411f7b48e98692951395c5c17d069c822cc1d0eae0f

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 14 см. в разделе Обновления ограничений интерфейса, не входящего в SDK, в Android 14 .

Андроид 13

Для Android 13 (уровень API 33) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: 233a277aa8ac475b6df61bffd95665d86aac6eb2ad187b90bf42a98f5f2a11a3

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 13, включая предлагаемые публичные альтернативы API для API, которые условно заблокированы в Android 13, см. в разделе Обновления ограничений интерфейсов, не входящих в SDK, в Android 13 .

Андроид 12

Для Android 12 (уровень API 31) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: 40674ff4291eb268f86561bf687e69dbd013df9ec9531a460404532a4ac9a761

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 12, включая предлагаемые публичные альтернативы API для API, которые условно заблокированы в Android 12, см. в разделе Изменения в списке для Android 12 .

Андроид 11

Для Android 11 (уровень API 30) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: a19d839f4f61dc9c94960ae977b2e0f3eb30f880ba1ffe5108e790010b477a56

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 11, включая предлагаемые публичные альтернативы API для API, которые условно заблокированы в Android 11, см. в разделе Изменения в списке для Android 11 .

андроид 10

Для Android 10 (уровень API 29) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: f22a59c215e752777a114bd9b07b0b6b4aedfc8e49e6efca0f99681771c5bfeb

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 10, включая предлагаемые публичные альтернативы API для API, которые условно заблокированы в Android 10, см. в разделе Изменения в списке для Android 10 .

Андроид 9

Для Android 9 (уровень API 28) следующий текстовый файл содержит список API, не входящих в SDK, которые не ограничены (внесены в серый список): hiddenapi-light-greylist.txt .

Список заблокированных ( blacklist ) и список условно заблокированных API (темно-серый список) формируются во время сборки.

Генерация списков из AOSP

При работе с AOSP вы можете сгенерировать файл hiddenapi-flags.csv , содержащий все интерфейсы, не входящие в SDK, и соответствующие им списки. Для этого загрузите исходный код AOSP и выполните следующую команду:

m out/soong/hiddenapi/hiddenapi-flags.csv

Затем вы можете найти файл в следующем месте:

out/soong/hiddenapi/hiddenapi-flags.csv

Ожидаемое поведение при доступе к ограниченным интерфейсам, не относящимся к SDK

В следующей таблице описано поведение, которого можно ожидать, если ваше приложение попытается получить доступ к интерфейсу, не являющемуся SDK, который входит в черный список.

Средства доступа Результат
Инструкция Dalvik, ссылающаяся на поле Выдана ошибка NoSuchFieldError
Инструкция Dalvik, ссылающаяся на метод Выдана ошибка NoSuchMethodError
Отражение с использованием Class.getDeclaredField() или Class.getField() Выброшено исключение NoSuchFieldException
Отражение с использованием Class.getDeclaredMethod() , Class.getMethod() NoSuchMethodException выброшено
Отражение с использованием Class.getDeclaredFields() , Class.getFields() Не входящие в SDK члены отсутствуют в результатах
Отражение с использованием Class.getDeclaredMethods() , Class.getMethods() Не входящие в SDK члены отсутствуют в результатах
JNI с использованием env->GetFieldID() Возвращено NULL , выдано NoSuchFieldError
JNI с использованием env->GetMethodID() Возвращено NULL , выдано NoSuchMethodError

Протестируйте свое приложение на наличие интерфейсов, не относящихся к SDK

Существует несколько методов, которые можно использовать для тестирования интерфейсов, не относящихся к SDK, в вашем приложении.

Тестирование с использованием отлаживаемого приложения

Вы можете протестировать интерфейсы, не относящиеся к SDK, создав и запустив отлаживаемое приложение на устройстве или эмуляторе под управлением Android 9 (уровень API 28) или выше. Убедитесь, что используемое вами устройство или эмулятор соответствует целевому уровню API вашего приложения.

При выполнении тестов в вашем приложении система выводит сообщение журнала, если ваше приложение обращается к определенным интерфейсам, не относящимся к SDK. Вы можете проверить сообщения журнала вашего приложения, чтобы найти следующие сведения:

  • Объявляющий класс, имя и тип (в формате, используемом средой выполнения Android).
  • Способы доступа: либо связывание, либо использование отражения, либо использование JNI.
  • К какому списку относится интерфейс, не являющийся SDK.

Вы можете использовать adb logcat для доступа к этим сообщениям журнала, которые отображаются под PID запущенного приложения. Например, запись в журнале может выглядеть следующим образом:

Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

Тестирование с использованием StrictMode API

Вы также можете протестировать интерфейсы, не относящиеся к SDK, с помощью StrictMode API. Используйте метод detectNonSdkApiUsage , чтобы включить это. После включения StrictMode API вы можете получать обратный вызов для каждого использования интерфейса, не относящегося к SDK, с помощью penaltyListener , где вы можете реализовать пользовательскую обработку. Объект Violation , предоставленный в обратном вызове, является производным от Throwable , а вложенная трассировка стека предоставляет контекст использования.

Тест с использованием инструмента veridex

Вы также можете запустить инструмент статического анализа veridex на вашем APK. Инструмент veridex сканирует всю кодовую базу APK, включая любые сторонние библиотеки, и сообщает о любых случаях использования интерфейсов, не относящихся к SDK, которые он находит.

Ограничения инструмента veridex включают следующее:

  • Он не может обнаружить вызовы через JNI.
  • Он может обнаружить только подмножество вызовов посредством отражения.
  • Анализ неактивных путей кода ограничивается проверками на уровне API.
  • Его можно запустить только на машинах, поддерживающих инструкции SSE4.2 и POPCNT.

Окна

Собственные двоичные файлы Windows не предоставляются, но вы можете запустить инструмент veridex в Windows, выполнив двоичные файлы Linux с помощью подсистемы Windows для Linux (WSL). Перед выполнением шагов в этом разделе установите WSL и выберите Ubuntu в качестве дистрибутива Linux.

После установки Ubuntu запустите терминал Ubuntu и выполните следующие действия:

  1. Загрузите инструмент veridex из репозитория готовых сборок среды выполнения Android.
  2. Извлеките содержимое файла appcompat.tar.gz .
  3. В извлеченной папке найдите файл veridex-linux.zip и извлеките его.
  4. Перейдите в распакованную папку и выполните следующую команду, где your-app.apk — это APK, который вы хотите протестировать:

    ./appcompat.sh --dex-file=your-app.apk
    

macOS

Чтобы запустить инструмент veridex на macOS, выполните следующие действия:

  1. Загрузите инструмент veridex из репозитория готовых сборок среды выполнения Android.
  2. Извлеките содержимое файла appcompat.tar.gz .
  3. В извлеченной папке найдите файл veridex-mac.zip и извлеките его.
  4. Перейдите в распакованную папку и выполните следующую команду, где /path-from-root/your-app.apk — это путь к APK-файлу, который вы хотите протестировать, начиная с корневого каталога вашей системы:

    ./appcompat.sh --dex-file=/path-from-root/your-app.apk
    

линукс

Чтобы запустить инструмент veridex в Linux, выполните следующие действия:

  1. Загрузите инструмент veridex из репозитория готовых сборок среды выполнения Android.
  2. Извлеките содержимое файла appcompat.tar.gz .
  3. В извлеченной папке найдите файл veridex-linux.zip и извлеките его.
  4. Перейдите в распакованную папку и выполните следующую команду, где your-app.apk — это APK, который вы хотите протестировать:

    ./appcompat.sh --dex-file=your-app.apk
    

Тестирование с помощью инструмента Android Studio lint

Всякий раз, когда вы создаете приложение в Android Studio, инструмент lint проверяет ваш код на наличие потенциальных проблем. Если ваше приложение использует интерфейсы, не относящиеся к SDK, вы можете увидеть ошибки сборки или предупреждения, в зависимости от того, к какому списку относятся эти интерфейсы.

Вы также можете запустить инструмент lint из командной строки или вручную запустить проверку определенного проекта, папки или файла.

Тест с использованием Play Console

Когда вы загружаете свое приложение в тестовую версию в Play Console, оно автоматически тестируется на наличие потенциальных проблем и создается отчет о предварительном запуске. Если ваше приложение использует интерфейсы, не относящиеся к SDK, в отчете о предварительном запуске отображается ошибка или предупреждение в зависимости от того, к какому списку относятся эти интерфейсы.

Дополнительную информацию см. в разделе «Совместимость с Android» статьи Использование отчетов о предварительных запусках для выявления проблем .

Запросить новый публичный API

Если вы не можете найти альтернативу использованию интерфейса, отличного от SDK, для функции вашего приложения, вы можете запросить новый публичный API, создав запрос на функцию в нашем трекере ошибок.

При создании запроса на функцию предоставьте следующую информацию:

  • Какой неподдерживаемый API вы используете, включая полный дескриптор, указанный в сообщении Accessing hidden ... logcat.
  • Почему вам необходимо использовать эти API, включая сведения о высокоуровневых функциях, для которых необходим API, а не только низкоуровневые сведения.
  • Почему любые связанные публичные API SDK недостаточны для ваших целей.
  • Какие еще альтернативы вы пробовали и почему они не сработали?

Предоставляя эти данные в своем запросе на функцию, вы увеличиваете вероятность предоставления нового публичного API.

Другие вопросы

В этом разделе приведены ответы на некоторые вопросы, которые часто задают разработчики:

Общие вопросы

Как Google может быть уверена, что сможет отслеживать потребности всех приложений с помощью IssueTracker?

Первоначальные списки для Android 9 (уровень API 28) были созданы путем статического анализа приложений, который был дополнен с использованием следующих методов:

  • ручное тестирование лучших приложений Play и не-Play
  • внутренние отчеты
  • автоматический сбор данных от внутренних пользователей
  • предварительные отчеты разработчиков
  • дополнительный статический анализ, который был разработан для консервативного включения большего количества ложных срабатываний

При оценке списков для каждого нового выпуска мы учитываем использование API, а также отзывы разработчиков через систему отслеживания ошибок.

Как включить доступ к интерфейсам, не относящимся к SDK?

Вы можете включить доступ к интерфейсам, не относящимся к SDK, на устройствах разработки, используя команды adb для изменения политики принудительного применения API. Команды, которые вы используете, различаются в зависимости от уровня API. Эти команды не требуют рутированного устройства.

Android 10 (уровень API 29) или выше

Чтобы включить доступ, используйте следующий adb

команда:

adb shell settings put global hidden_api_policy  1

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

adb shell settings delete global hidden_api_policy
Android 9 (уровень API 28)

Чтобы включить доступ, используйте следующие команды adb:

adb shell settings put global hidden_api_policy_pre_p_apps  1
adb shell settings put global hidden_api_policy_p_apps 1

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

adb shell settings delete global hidden_api_policy_pre_p_apps
adb shell settings delete global hidden_api_policy_p_apps

Вы можете установить целое число в политике принудительного использования API на одно из следующих значений:

  • 0: Отключить все обнаружения интерфейсов, отличных от SDK. Использование этого параметра отключает все сообщения журнала для использования интерфейсов, отличных от SDK, и не позволяет вам тестировать приложение с помощью StrictMode API . Этот параметр не рекомендуется.
  • 1: Включить доступ ко всем не-SDK интерфейсам, но выводить сообщения журнала с предупреждениями для любого использования не-SDK интерфейса. Использование этого параметра также позволяет вам тестировать ваше приложение с помощью StrictMode API .
  • 2: Запретить использование интерфейсов, не относящихся к SDK, которые входят в черный список или условно заблокированы для вашего целевого уровня API .

Вопросы о списках интерфейсов, не входящих в SDK

Где я могу найти списки API, не входящих в SDK, в образе системы?

Они закодированы в битах флага доступа к полю и методу в файлах платформы dex. В образе системы нет отдельного файла, который содержал бы эти списки.

Одинаковы ли списки API не-SDK на разных OEM-устройствах с одинаковыми версиями Android?

OEM-производители могут добавлять собственные интерфейсы в черный список (blocklist), но не могут удалять интерфейсы из списков API AOSP non-SDK. CDD предотвращает такие изменения, а тесты CTS гарантируют, что Android Runtime применяет список.

Существуют ли какие-либо ограничения на использование не-NDK-интерфейсов в нативном коде?

Android SDK включает интерфейсы Java. Платформа начала ограничивать доступ к интерфейсам, отличным от NDK, для собственного кода C/C++ в Android 7 (уровень API 26). Для получения дополнительной информации см. Улучшение стабильности с помощью ограничений символов Private C/C++ в Android N.

Планируется ли ограничить манипуляции с файлами dex2oat или DEX?

У нас нет активных планов по ограничению доступа к двоичному файлу dex2oat, но мы не намерены делать формат файла DEX стабильным или общедоступным интерфейсом за пределами частей, которые публично указаны в формате исполняемого файла Dalvik . Мы оставляем за собой право изменять или удалять dex2oat и неуказанные части формата DEX в любое время. Также обратите внимание, что производные файлы, созданные dex2oat, такие как ODEX (также известный как OAT), VDEX и CDEX, являются неуказанными форматами.

Что делать, если важный сторонний SDK (например, обфускатор) не может избежать использования не-SDK интерфейсов, но обязуется поддерживать совместимость с будущими версиями Android? Может ли Android отказаться от своих требований совместимости в этом случае?

У нас нет планов отказаться от требований совместимости на основе каждого SDK. Если разработчик SDK может поддерживать совместимость только в зависимости от интерфейсов в неподдерживаемых (ранее серых) списках, он должен начать планировать миграцию на интерфейсы SDK или другие альтернативы и запрашивать новый публичный API всякий раз, когда он не может найти альтернативу использованию интерфейса, отличного от SDK.

Распространяются ли ограничения интерфейса, не относящегося к SDK, на все приложения, включая системные и сторонние приложения, а не только на сторонние приложения?

Да, однако мы исключаем приложения, подписанные с помощью ключа платформы, и некоторые приложения образа системы. Обратите внимание, что эти исключения применяются только к приложениям, которые являются частью образа системы (или обновленным приложениям образа системы). Список предназначен только для приложений, которые создаются на основе API частной платформы, а не API SDK (где LOCAL_PRIVATE_PLATFORM_APIS := true ).

,

Начиная с Android 9 (уровень API 28) платформа ограничивает, какие интерфейсы, не относящиеся к SDK, может использовать ваше приложение. Эти ограничения применяются всякий раз, когда приложение ссылается на интерфейс, не относящийся к SDK, или пытается получить его дескриптор с помощью отражения или JNI. Эти ограничения были введены, чтобы помочь улучшить опыт пользователя и разработчика и снизить риски сбоев для пользователей и экстренных развертываний для разработчиков. Для получения дополнительной информации об этом решении см. раздел Улучшение стабильности путем сокращения использования интерфейсов, не относящихся к SDK .

Различия между интерфейсами SDK и не-SDK

Вообще говоря, публичные интерфейсы SDK — это те, которые задокументированы в индексе пакетов Android framework. Обработка интерфейсов, не относящихся к SDK, — это деталь реализации, которую API абстрагирует, поэтому эти интерфейсы могут быть изменены без предварительного уведомления.

Чтобы избежать сбоев и неожиданного поведения, приложения должны использовать только официально задокументированные части классов в SDK. Это также означает, что вы не должны получать доступ к методам или полям, которые не перечислены в SDK, когда вы взаимодействуете с классом с использованием таких механизмов, как отражение.

Списки API не-SDK

С каждым выпуском Android ограничиваются дополнительные интерфейсы, не относящиеся к SDK. Мы знаем, что эти ограничения могут повлиять на ваш рабочий процесс выпуска, и мы хотим убедиться, что у вас есть инструменты для обнаружения использования интерфейсов, не относящихся к SDK, возможность дать нам отзыв и время для планирования и адаптации к новым политикам.

Чтобы минимизировать влияние ограничений, не относящихся к SDK, на ваш рабочий процесс разработки, интерфейсы, не относящиеся к SDK, разделены на списки, которые определяют, насколько строго ограничено их использование, в зависимости от того, какой уровень API является целевым. В следующей таблице описывается каждый из этих списков:

Список Кодовые теги Описание
Черный список
  • blocked
  • Устаревшее: blacklist
Интерфейсы, не входящие в SDK, которые вы не можете использовать независимо от целевого уровня API вашего приложения. Если ваше приложение попытается получить доступ к одному из этих интерфейсов, система выдаст ошибку .
Условно заблокирован
  • max-target-x
  • Устаревший: greylist-max-x

Начиная с Android 9 (уровень API 28) каждый уровень API имеет интерфейсы, не относящиеся к SDK, которые ограничиваются, когда приложение нацелено на этот уровень API.

Эти списки помечены максимальным уровнем API ( max-target-x ), на который приложение может ориентироваться, прежде чем приложение больше не сможет получать доступ к интерфейсам не-SDK в этом списке. Например, интерфейс не-SDK, который не был заблокирован в Android Pie, но теперь заблокирован в Android 10, является частью списка max-target-p ( greylist-max-p ), где «p» означает Pie или Android 9 (уровень API 28).

Если ваше приложение пытается получить доступ к интерфейсу, который ограничен для вашего целевого уровня API, система ведет себя так, как будто API является частью черного списка .

Неподдерживаемый
  • unsupported
  • Устаревший: greylist
Интерфейсы, не относящиеся к SDK, которые не ограничены и могут использоваться вашим приложением. Однако обратите внимание, что эти интерфейсы не поддерживаются и могут быть изменены без уведомления. Ожидайте, что эти интерфейсы будут условно заблокированы в будущих версиях Android в списке max-target-x .
SDK
  • Оба public-api и sdk
  • Устаревшие: как public-api , так и whitelist
Интерфейсы, которые можно свободно использовать и которые теперь поддерживаются как часть официально документированного индекса пакетов Android.
Тестовые API
  • test-api
Интерфейсы, которые используются для внутреннего тестирования системы, такие как API, которые облегчают тестирование через Compatibility Test Suite (CTS). Тестовые API не являются частью SDK. Начиная с Android 11 (API уровня 30) , тестовые API включены в черный список, поэтому приложениям не разрешено использовать их независимо от целевого уровня API. Все тестовые API не поддерживаются и могут быть изменены без предварительного уведомления, независимо от уровня API платформы.

Хотя вы можете использовать некоторые интерфейсы, не относящиеся к SDK (в зависимости от целевого уровня API вашего приложения), использование любого метода или поля, не относящегося к SDK, всегда несет высокий риск поломки вашего приложения. Если ваше приложение использует интерфейсы, не относящиеся к SDK, вам следует начать планировать миграцию на интерфейсы SDK или другие альтернативы. Если вы не можете найти альтернативу использованию интерфейса, не относящегося к SDK, для функции в вашем приложении, вам следует запросить новый публичный API .

Определите, к какому списку принадлежит интерфейс

Списки интерфейсов, не входящих в SDK, создаются как часть платформы. Информацию о каждом выпуске Android см. в следующих разделах.

Андроид 16

Для Android 16 (уровень API 36) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: 9102af02fe6ab68b92464bdff5e5b09f3bd62c65d1130aaf85d3296f17d38074

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 16 см. в разделе Обновления ограничений интерфейса, не входящего в SDK, в Android 16 .

Андроид 15

Для Android 15 (уровень API 35) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: 40134e205e58922a708c453726b279a296e6a1f34a988abd90cec0f3432ea5a9

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 15 см. в разделе Обновления ограничений интерфейса, не входящего в SDK, в Android 15 .

Андроид 14

Для Android 14 (уровень API 34) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: 7e00db074cbe51c51ff4b411f7b48e98692951395c5c17d069c822cc1d0eae0f

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 14 см. в разделе Обновления ограничений интерфейса, не входящего в SDK, в Android 14 .

Андроид 13

Для Android 13 (уровень API 33) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: 233a277aa8ac475b6df61bffd95665d86aac6eb2ad187b90bf42a98f5f2a11a3

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 13, включая предлагаемые публичные альтернативы API для API, которые условно заблокированы в Android 13, см. в разделе Обновления ограничений интерфейсов, не входящих в SDK, в Android 13 .

Андроид 12

Для Android 12 (уровень API 31) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: 40674ff4291eb268f86561bf687e69dbd013df9ec9531a460404532a4ac9a761

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 12, включая предлагаемые публичные альтернативы API для API, которые условно заблокированы в Android 12, см. в разделе Изменения в списке для Android 12 .

Андроид 11

Для Android 11 (уровень API 30) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: a19d839f4f61dc9c94960ae977b2e0f3eb30f880ba1ffe5108e790010b477a56

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 11, включая предлагаемые публичные альтернативы API для API, которые условно заблокированы в Android 11, см. в разделе Изменения в списке для Android 11 .

андроид 10

Для Android 10 (уровень API 29) вы можете загрузить следующий файл, описывающий все интерфейсы, не входящие в SDK, и соответствующие им списки:

Файл: hiddenapi-flags.csv

Контрольная сумма SHA-256: f22a59c215e752777a114bd9b07b0b6b4aedfc8e49e6efca0f99681771c5bfeb

Дополнительную информацию об изменениях в списке API, не входящих в SDK, в Android 10, включая предлагаемые публичные альтернативы API для API, которые условно заблокированы в Android 10, см. в разделе Изменения в списке для Android 10 .

Андроид 9

Для Android 9 (уровень API 28) следующий текстовый файл содержит список API, не входящих в SDK, которые не ограничены (внесены в серый список): hiddenapi-light-greylist.txt .

Список заблокированных ( blacklist ) и список условно заблокированных API (темно-серый список) формируются во время сборки.

Генерация списков из AOSP

При работе с AOSP вы можете сгенерировать файл hiddenapi-flags.csv , содержащий все интерфейсы, не входящие в SDK, и соответствующие им списки. Для этого загрузите исходный код AOSP и выполните следующую команду:

m out/soong/hiddenapi/hiddenapi-flags.csv

Затем вы можете найти файл в следующем месте:

out/soong/hiddenapi/hiddenapi-flags.csv

Ожидаемое поведение при доступе к ограниченным интерфейсам, не относящимся к SDK

В следующей таблице описано поведение, которого можно ожидать, если ваше приложение попытается получить доступ к интерфейсу, не являющемуся SDK, который входит в черный список.

Средства доступа Результат
Инструкция Dalvik, ссылающаяся на поле Выдана ошибка NoSuchFieldError
Инструкция Dalvik, ссылающаяся на метод Выдана ошибка NoSuchMethodError
Отражение с использованием Class.getDeclaredField() или Class.getField() Выброшено исключение NoSuchFieldException
Отражение с использованием Class.getDeclaredMethod() , Class.getMethod() NoSuchMethodException выброшено
Отражение с использованием Class.getDeclaredFields() , Class.getFields() Не входящие в SDK члены отсутствуют в результатах
Отражение с использованием Class.getDeclaredMethods() , Class.getMethods() Не входящие в SDK члены отсутствуют в результатах
JNI с использованием env->GetFieldID() Возвращено NULL , выдано NoSuchFieldError
JNI с использованием env->GetMethodID() Возвращено NULL , выдано NoSuchMethodError

Протестируйте свое приложение на наличие интерфейсов, не относящихся к SDK

Существует несколько методов, которые можно использовать для тестирования интерфейсов, не относящихся к SDK, в вашем приложении.

Тестирование с использованием отлаживаемого приложения

Вы можете протестировать интерфейсы, не относящиеся к SDK, создав и запустив отлаживаемое приложение на устройстве или эмуляторе под управлением Android 9 (уровень API 28) или выше. Убедитесь, что используемое вами устройство или эмулятор соответствует целевому уровню API вашего приложения.

При выполнении тестов в вашем приложении система выводит сообщение журнала, если ваше приложение обращается к определенным интерфейсам, не относящимся к SDK. Вы можете проверить сообщения журнала вашего приложения, чтобы найти следующие сведения:

  • Объявляющий класс, имя и тип (в формате, используемом средой выполнения Android).
  • Способы доступа: либо связывание, либо использование отражения, либо использование JNI.
  • К какому списку относится интерфейс, не являющийся SDK.

Вы можете использовать adb logcat для доступа к этим сообщениям журнала, которые отображаются под PID запущенного приложения. Например, запись в журнале может выглядеть следующим образом:

Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

Тестирование с использованием StrictMode API

Вы также можете протестировать интерфейсы, не относящиеся к SDK, с помощью StrictMode API. Используйте метод detectNonSdkApiUsage , чтобы включить это. После включения StrictMode API вы можете получать обратный вызов для каждого использования интерфейса, не относящегося к SDK, с помощью penaltyListener , где вы можете реализовать пользовательскую обработку. Объект Violation , предоставленный в обратном вызове, является производным от Throwable , а вложенная трассировка стека предоставляет контекст использования.

Тест с использованием инструмента veridex

Вы также можете запустить инструмент статического анализа veridex на вашем APK. Инструмент veridex сканирует всю кодовую базу APK, включая любые сторонние библиотеки, и сообщает о любых случаях использования интерфейсов, не относящихся к SDK, которые он находит.

Ограничения инструмента veridex включают следующее:

  • Он не может обнаружить вызовы через JNI.
  • Он может обнаружить только подмножество вызовов посредством отражения.
  • Анализ неактивных путей кода ограничивается проверками на уровне API.
  • Его можно запустить только на машинах, поддерживающих инструкции SSE4.2 и POPCNT.

Окна

Собственные двоичные файлы Windows не предоставляются, но вы можете запустить инструмент veridex в Windows, выполнив двоичные файлы Linux с помощью подсистемы Windows для Linux (WSL). Перед выполнением шагов в этом разделе установите WSL и выберите Ubuntu в качестве дистрибутива Linux.

После установки Ubuntu запустите терминал Ubuntu и выполните следующие действия:

  1. Загрузите инструмент veridex из репозитория готовых сборок среды выполнения Android.
  2. Извлеките содержимое файла appcompat.tar.gz .
  3. В извлеченной папке найдите файл veridex-linux.zip и извлеките его.
  4. Перейдите в распакованную папку и выполните следующую команду, где your-app.apk — это APK, который вы хотите протестировать:

    ./appcompat.sh --dex-file=your-app.apk
    

macOS

Чтобы запустить инструмент veridex на macOS, выполните следующие действия:

  1. Загрузите инструмент veridex из репозитория готовых сборок среды выполнения Android.
  2. Извлеките содержимое файла appcompat.tar.gz .
  3. В извлеченной папке найдите файл veridex-mac.zip и извлеките его.
  4. Перейдите в распакованную папку и выполните следующую команду, где /path-from-root/your-app.apk — это путь к APK-файлу, который вы хотите протестировать, начиная с корневого каталога вашей системы:

    ./appcompat.sh --dex-file=/path-from-root/your-app.apk
    

линукс

Чтобы запустить инструмент veridex в Linux, выполните следующие действия:

  1. Загрузите инструмент veridex из репозитория готовых сборок среды выполнения Android.
  2. Извлеките содержимое файла appcompat.tar.gz .
  3. В извлеченной папке найдите файл veridex-linux.zip и извлеките его.
  4. Перейдите в распакованную папку и выполните следующую команду, где your-app.apk — это APK, который вы хотите протестировать:

    ./appcompat.sh --dex-file=your-app.apk
    

Тестирование с помощью инструмента Android Studio lint

Всякий раз, когда вы создаете приложение в Android Studio, инструмент lint проверяет ваш код на наличие потенциальных проблем. Если ваше приложение использует интерфейсы, не относящиеся к SDK, вы можете увидеть ошибки сборки или предупреждения, в зависимости от того, к какому списку относятся эти интерфейсы.

Вы также можете запустить инструмент lint из командной строки или вручную запустить проверку определенного проекта, папки или файла.

Тест с использованием Play Console

Когда вы загружаете свое приложение в тестовую версию в Play Console, оно автоматически тестируется на наличие потенциальных проблем и создается отчет о предварительном запуске. Если ваше приложение использует интерфейсы, не относящиеся к SDK, в отчете о предварительном запуске отображается ошибка или предупреждение в зависимости от того, к какому списку относятся эти интерфейсы.

Дополнительную информацию см. в разделе «Совместимость с Android» статьи Использование отчетов о предварительных запусках для выявления проблем .

Запросить новый публичный API

Если вы не можете найти альтернативу использованию не-SDK-интерфейса для функции в вашем приложении, вы можете запросить новый публичный API, создав запрос функции в нашем трекере.

При создании запроса функции предоставьте следующую информацию:

  • Какой не поддерживается API, который вы используете, включая полный дескриптор, который можно увидеть в Accessing hidden ... сообщении LogCat.
  • Почему вам нужно использовать эти API, в том числе подробности о функции высокого уровня, для которой необходим API, а не только детали низкого уровня.
  • Почему любые связанные публичные API SDK недостаточны для ваших целей.
  • Любые другие альтернативы, которые вы попробовали, и почему они не сработали.

Когда вы предоставляете эти данные в своем запросе функции, вы увеличиваете вероятность того, что новый публичный API будет предоставлен.

Другие вопросы

Этот раздел включает в себя некоторые ответы на другие вопросы, которые разработчики часто задавали:

Общие вопросы

Как Google может быть уверен, что они могут запечатлеть потребности всех приложений через EvesueTracker?

Мы создали первоначальные списки для Android 9 (API -уровень 28) посредством статического анализа приложений, который был дополнен с использованием следующих методов:

  • Ручное тестирование приложений Top Play и Non Play
  • Внутренние отчеты
  • Автоматический сбор данных от внутренних пользователей
  • Предварительный просмотр разработчиков отчеты
  • Дополнительный статический анализ, который был разработан для консервативности, включает в себя больше ложных срабатываний

Когда мы оцениваем списки для каждого нового выпуска, мы учитываем использование API, а также обратную связь разработчика через трекер выпуска.

Как я могу включить доступ к не-SDK-интерфейсам?

Вы можете включить доступ к не-SDK-интерфейсам на устройствах разработки, используя команды ADB для изменения политики обеспечения соблюдения API. Команды, которые вы используете, различаются, в зависимости от уровня API. Эти команды не требуют корневого устройства.

Android 10 (API -уровень 29) или выше

Чтобы включить доступ, используйте следующую ADB

Команда:

adb shell settings put global hidden_api_policy  1

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

adb shell settings delete global hidden_api_policy
Android 9 (уровень API 28)

Чтобы включить доступ, используйте следующие команды ADB:

adb shell settings put global hidden_api_policy_pre_p_apps  1
adb shell settings put global hidden_api_policy_p_apps 1

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

adb shell settings delete global hidden_api_policy_pre_p_apps
adb shell settings delete global hidden_api_policy_p_apps

Вы можете установить целое число в политике применения API на одно из следующих значений:

  • 0: Отключить все обнаружение не-SDK интерфейсов. Использование этой настройки отключает все сообщения журнала для использования интерфейса без SDK и не позволяет вам тестировать ваше приложение с помощью API StrictMode . Эта настройка не рекомендуется.
  • 1: Включите доступ ко всем не-SDK-интерфейсам, но печатайте сообщения журнала с предупреждениями для любого использования интерфейса, не связанного с SDK. Использование этой настройки также позволяет протестировать ваше приложение , используя API StrictMode .
  • 2: запретить использование не-SDK-интерфейсов, которые принадлежат блочному списку или условно заблокированы для вашего целевого уровня API .

Вопросы о списках интерфейса без SDK

Где я могу найти списки API не-SDK на изображении системы?

Они кодируются в полевых и методах доступа к методам флага в файлах DEX платформы. В образе системы нет отдельного файла, который содержит эти списки.

Является ли API не SDK перечислены одинаковые на разных устройствах OEM с одинаковыми версиями Android?

OEM-производители могут добавить свои собственные интерфейсы в Blocklist (BlackList), но они не могут удалить интерфейсы из списков API API API API ASOSP. CDD предотвращает такие изменения, и тесты CTS гарантируют, что время выполнения Android обеспечивает соблюдение списка.

Есть ли какие-либо ограничения на не-NDK-интерфейсы в собственном коде?

Android SDK включает в себя интерфейсы Java. Платформа начала ограничивать доступ к не-NDK-интерфейсам для нативного кода C/C ++ в Android 7 (API-уровне 26). Для получения дополнительной информации см. Улучшение стабильности с частными ограничениями символов C/C ++ в Android N.

Есть ли план ограничения манипуляции с файлами DEX2OAT или DEX?

У нас нет активных планов по ограничению доступа к двоичному файлу DEX2OAT, но мы не намерены, чтобы формат файла DEX был стабильным или публичным интерфейсом за пределами порций, которые публично указаны в исполняемом формате Dalvik . Мы оставляем за собой право изменять или устранять DEX2OAT и неопределенные части формата DEX в любое время. Также обратите внимание, что полученные файлы, созданные Dex2oat, такие как ODEX (также известный как OAT), VDEX и CDEX, являются неуказанными форматами.

Что, если важнейший сторонний SDK (например, сфускатор) не может избежать использования не-SDK-интерфейсов, но привержен ли поддерживать совместимость с будущими версиями Android? Может ли Android отказаться от требований к совместимости в этом случае?

У нас нет планов отказаться от требований к совместимости на основе SDK. Если разработчик SDK может поддерживать совместимость только в зависимости от интерфейсов в неподдерживаемых (ранее серых) списках, они должны начать планирование миграции в интерфейсы SDK или другие альтернативы и запросить новый публичный API , когда не могут найти альтернативу использованию интерфейса без SDK.

Применяются ли ограничения не-SDK интерфейса ко всем приложениям, включая системные и первоклассные приложения, а не только сторонние приложения?

Да, однако, мы освобождаем приложения, подписанные с ключом платформы и некоторыми приложениями системного изображения. Обратите внимание, что эти исключения применяются только к приложениям, которые являются частью изображения системы (или обновленных приложений системного изображения). Список предназначен только для приложений, которые строятся против API частной платформы, а не API SDK (где LOCAL_PRIVATE_PLATFORM_APIS := true ).