Поддержка размеров страниц 16 КБ.

Исторически сложилось так, что Android поддерживал только размеры страниц памяти 4 КБ, что оптимизировало производительность системной памяти для среднего объема общей памяти, который обычно имеется в устройствах Android. Начиная с Android 15, AOSP поддерживает устройства, настроенные на использование страницы размером 16 КБ (устройства 16 КБ). Если ваше приложение использует какие-либо библиотеки NDK , прямо или косвенно через SDK, вам потребуется пересобрать приложение, чтобы оно работало на этих устройствах с размером памяти 16 КБ.

Поскольку производители устройств продолжают создавать устройства с большим объемом физической памяти (ОЗУ), многие из этих устройств будут использовать размеры страниц 16 КБ (и, в конечном итоге, больше) для оптимизации производительности устройства. Добавление поддержки устройств с размером страницы 16 КБ позволяет вашему приложению работать на этих устройствах и помогает вашему приложению извлечь выгоду из связанных с этим улучшений производительности. Без перекомпиляции приложения могут не работать на устройствах с размером памяти 16 КБ, когда они будут выпущены в будущих выпусках Android.

Чтобы помочь вам добавить поддержку вашего приложения, мы предоставили рекомендации о том, как проверить, не затронуто ли ваше приложение , как пересобрать приложение (если применимо) и как протестировать приложение в среде размером 16 КБ с помощью эмуляторов (включая Android). 15 системных образов для эмулятора Android).

Преимущества и повышение производительности

配置为 16 KB 页面的设备平均使用的内存会略多,但系统和应用性能也会有所提升:

  • 在系统面临内存压力时缩短应用启动时间:平均降低了 3.16%,对于我们测试过的一些应用而言,改进幅度更显著(提升幅度高达 30%)
  • 降低应用启动时的功耗:平均降低 4.56%
  • 相机启动速度更快:平均热启动速度加快 4.48%,冷启动速度平均加快 6.60%
  • 缩短了系统启动时间:平均缩短了 1.5%(约 0.8 秒)

这些改进基于我们的初始测试,实际设备上的结果可能会有所不同。在继续测试的过程中,我们会进一步分析应用的潜在益处。

Проверьте, не затронуто ли ваше приложение

如果您的应用使用任何原生代码,则您应重新构建支持 16 KB 设备的应用。如果您不确定自己的应用是否使用了原生代码,可以使用 APK 分析器来确定是否存在任何原生代码

如果您的应用仅使用以 Java 编程语言或 Kotlin 编写的代码(包括所有库或 SDK),那么该应用已经支持 16 KB 设备。不过,我们建议您在 16 KB 的环境中测试应用,以确认应用行为是否存在意外回归问题。

Использует ли ваше приложение собственный код?

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

  • Ваше приложение использует любой (собственный) код C/C++. Если ваше приложение использует Android NDK , то оно использует собственный код.
  • Ваше приложение связано с любыми сторонними собственными библиотеками или зависимостями, которые их используют.
  • Ваше приложение создано сторонним разработчиком приложений, который использует собственные библиотеки на устройстве.

Определите собственные библиотеки с помощью APK Analyzer

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

  1. Откройте Android Studio , затем нажмите «Файл» > «Открыть» и выберите любой проект.
  2. В строке меню нажмите «Сборка» > «Анализ APK…».

    Пункт меню Studio Build для запуска APK Analyzer

  3. Выберите APK, который хотите проанализировать.

  4. Просмотрите папку lib , в которой хранятся файлы общих объектов ( .so ), если таковые имеются. Если присутствуют какие-либо общие объектные файлы, ваше приложение использует собственный код. Если файлы общих объектов отсутствуют или папка lib отсутствует, ваше приложение не использует собственный код.

    Представление анализатора APK, показывающее наличие файлов общих объектов.

Создайте свое приложение с поддержкой устройств с размером памяти 16 КБ.

Для поддержки устройств с размером памяти 16 КБ приложения, использующие собственный код, должны выполнить действия, описанные в следующих разделах.

Обновите упаковку ваших общих библиотек.

Мы рекомендуем вам перейти на AGP версии 8.3 или выше и использовать несжатые общие библиотеки.

AGP версии 8.3 или выше

Устройствам размером 16 КБ требуются приложения, поставляемые с несжатыми общими библиотеками, для выравнивания их по границе 16 КБ, выровненной по zip-архиву. Для этого вам необходимо обновить плагин Android Gradle (AGP) до версии 8.3 или выше. Подробную информацию о процессе обновления см. в разделе «Помощник по обновлению плагина Android Gradle» .

AGP версии 8.2 или ниже

Если вы не можете обновить AGP до версии 8.3 или выше, альтернативой является переключение на использование сжатых общих библиотек. Обновите конфигурацию Gradle, чтобы Gradle сжимал ваши общие библиотеки при упаковке вашего приложения, чтобы избежать проблем с установкой приложения с несогласованными общими библиотеками.

классный

В файле build.gradle добавьте следующую опцию:

android {
  ...
  packagingOptions {
      jniLibs {
        useLegacyPackaging true
      }
  }
}

Котлин

В файле build.gradle.kts добавьте следующую опцию:

android {
  ...
  packagingOptions {
      jniLibs {
        useLegacyPackaging = true
      }
  }
}

Скомпилируйте приложение, используя выравнивание ELF размером 16 КБ.

Для работы вашего приложения устройствам размером 16 КБ требуется, чтобы сегменты ELF общих библиотек были правильно выровнены с использованием выравнивания ELF 16 КБ.

Чтобы скомпилировать приложение с использованием выравнивания ELF размером 16 КБ, выполните действия, описанные в одном из следующих разделов, в зависимости от используемой версии Android NDK.

Android NDK r26 и более ранние версии

Чтобы поддерживать компиляцию общих библиотек размером 16 КБ с помощью Android NDK версии r26 или ниже, вам необходимо обновить конфигурацию ndk-build или cmake следующим образом:

ndk-сборка

Обновите свой Android.mk , чтобы включить выравнивание ELF размером 16 КБ:

LOCAL_LDFLAGS += "-Wl,-z,max-page-size=16384"

CMake

Обновите файл CMakeLists.txt , чтобы включить выравнивание ELF размером 16 КБ:

target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384")

Android NDK r27 и выше

Чтобы поддерживать компиляцию общих библиотек размером 16 КБ с Android NDK версии r27 и выше, вам необходимо обновить флаги ndk-build , build.gradle , build.gradle.kts или компоновщика следующим образом:

ndk-сборка

В вашем Application.mk :

APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true

классный

В файле build.gradle установите аргумент -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON :

android {
  ...
  defaultConfig {
    ...
    // This block is different from the one you use to link Gradle
    // to your CMake or ndk-build script.
    externalNativeBuild {
      // For ndk-build, instead use the ndkBuild block.
      cmake {
        // Passes optional arguments to CMake.
        arguments "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
      }
    }
  }
}

Котлин

В файле build.gradle.kts установите аргумент -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON :

android {
  ...
  defaultConfig {
    ...
    // This block is different from the one you use to link Gradle
    // to your CMake or ndk-build script.
    externalNativeBuild {
      // For ndk-build, instead use the ndkBuild block.
      cmake {
        // Passes optional arguments to CMake.
        arguments += listOf("-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON")
      }
    }
  }
}

Другие системы сборки

Укажите следующие флаги компоновщика:

-Wl,-z,max-page-size=16384

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

Даже если ваше приложение выровнено по 16 КБ, оно может столкнуться с ошибками, если места в вашем коде предполагают, что устройство использует страницу определенного размера. Чтобы этого избежать, выполните следующие действия:

  1. Удалите все жестко запрограммированные зависимости, которые ссылаются на константу PAGE_SIZE , или экземпляры в логике вашего кода, которые предполагают, что размер страницы устройства составляет 4 КБ ( 4096 ).

    Вместо этого используйте getpagesize() или sysconf(_SC_PAGESIZE) .

  2. Найдите варианты использования mmap() и других API, требующих аргументов, выровненных по страницам, и при необходимости замените их альтернативами.

В некоторых случаях, если ваше приложение использует PAGE_SIZE в качестве удобного значения, не привязанного к базовому размеру страницы, это не приведет к сбою вашего приложения при использовании в режиме 16 КБ. Однако если это значение передается ядру с помощью mmap без MAP_FIXED , ядро ​​все равно использует всю страницу, что приводит к потере некоторой памяти. По этим причинам PAGE_SIZE не определен, если режим 16 КБ включен в NDK r27 и выше.

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

Протестируйте свое приложение в среде размером 16 КБ.

После того как вы создадите свое приложение с поддержкой устройств с размером памяти 16 КБ, вам нужно будет протестировать свое приложение в среде 16 КБ, чтобы увидеть, наблюдается ли в вашем приложении какие-либо регрессии. Для этого выполните следующие действия:

  1. Настройте Android 15 SDK .

  2. Настройте одну из следующих сред тестирования:

  3. Запустите тестовое устройство, затем выполните следующую команду, чтобы убедиться, что оно использует среду размером 16 КБ:

    adb shell getconf PAGE_SIZE
    

    Команда должна вернуть значение 16384 .

  4. Для всех общих библиотек убедитесь, что сегменты ELF общих библиотек выровнены правильно, используя выравнивание ELF по 16 КБ. Вы можете использовать этот скрипт, чтобы помочь в этом процессе:

    #!/bin/bash
    
    # usage: alignment.sh path to search for *.so files
    
    dir="$1"
    
    RED="\e[31m"
    GREEN="\e[32m"
    ENDCOLOR="\e[0m"
    
    matches="$(find $dir -name "*.so" -type f)"
    IFS=$'\n'
    for match in $matches; do
      res="$(objdump -p ${match} | grep LOAD | awk '{ print $NF }' | head -1)"
      if [[ $res =~ "2**14" ]] || [[ $res =~ "2**16" ]]; then
        echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
      else
        echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
      fi
    done
    
    1. Сохраните сценарий в файл, например alignment.sh .

    2. Извлеките APK-файл вашего приложения:

      unzip APK_NAME.apk -d /tmp/my_apk_out
      
    3. Запустите скрипт для извлеченных файлов в каталоге /tmp/my_apk_out :

      alignment.sh /tmp/my_apk_out | grep "arm64-v8a"
      

      Скрипт выводит либо ALIGNED , либо UNALIGNED для всех общих библиотек arm64-v8a .

    4. Если какие-либо общие библиотеки arm64-v8a НЕ UNALIGNED , вам необходимо обновить упаковку для этих библиотек , затем перекомпилировать приложение и повторно протестировать, выполнив действия, описанные в этом разделе.

  5. Выполните следующую команду zipalign , чтобы убедиться, что ваше приложение выровнено по размеру 16 КБ, где APK_NAME — это имя APK-файла вашего приложения:

    zipalign -c -P 16 -v 4 APK_NAME.apk
    
  6. Тщательно протестируйте свое приложение, уделяя особое внимание всем областям, на которые может повлиять изменение экземпляров кода, ссылающихся на определенные размеры страниц .

Настройте эмулятор Android с помощью образа системы Android 15 размером 16 КБ.

Чтобы настроить среду размером 16 КБ с помощью эмулятора Android, выполните следующие действия:

  1. Образы системы эмулятора Android 15 размером 16 КБ совместимы с Android Studio Jellyfish | 2023.3.1 или выше. Однако для получения наилучших результатов при работе с бета-версией Android 15 загрузите последнюю предварительную версию Android Studio.

    Помните, что вы можете оставить существующую версию Android Studio установленной, так как вы можете установить несколько версий одновременно .

  2. В Android Studio нажмите «Инструменты» > «Менеджер SDK» .

  3. На вкладке «Платформы SDK» установите флажок «Показать сведения о пакете» , затем разверните раздел «Предварительный просмотр Android VanillaIceCream» и выберите один или оба следующих образа системы эмулятора, в зависимости от виртуальных устройств, которые вы хотите создать:

    • API Google Экспериментальный размер страницы 16 тыс. Системный образ ARM 64 v8a
    • API Google Экспериментальный размер страницы 16 КБ Изображение системы Intel x86_64 Atom

    Загрузите образы системы эмулятора размером 16 КБ с помощью SDK Manager в Android Studio.

  4. Нажмите «Применить» > «ОК» , чтобы загрузить выбранные вами образы системы.

  5. Следуйте инструкциям по настройке виртуального устройства для Android 15 , а когда будет предложено выбрать образ системы, выберите загруженный вами образ системы размером 16 КБ. Если это не рекомендуется автоматически, вы можете найти системный образ размером 16 КБ на вкладке «Другие изображения» .

    Найдите изображение эмулятора размером 16 КБ на вкладке «Другие изображения».