Android 过去仅支持 4 KB 内存页面大小, 优化了系统内存性能,以针对 Android 设备通常具备的功能。从 Android 15 开始,AOSP 支持 配置为使用 16 KB (16 KB) 页面大小的设备 设备)。如果您的应用使用任何 NDK 库,请直接使用 或者通过 SDK 间接创建,那么,您需要重新构建自己的应用 支持这些 16KB 设备。
随着设备制造商不断打造出 物理内存 (RAM),许多此类设备都会采用 16KB(以及 页面大小以优化设备的性能。正在添加 支持 16 KB 页面大小的设备,可使您的应用在这些设备上运行 并有助于您的应用从相关的广告效果中获益 改进。如果不重新编译,应用可能无法在 16KB 设备上运行 在未来的 Android 版本中正式推出。
为帮助您为应用添加支持,我们提供了有关如何检查 如果您的应用受到影响 重新构建您的应用(如果适用),以及如何在 Google Play 中 使用模拟器(包括 Android 15)的 16 KB 环境 系统映像)。
优势和性能提升
配置为 16 KB 页面的设备平均使用的内存会略多,但系统和应用性能也会有所提升:
- 在系统面临内存压力时缩短应用启动时间:平均降低了 3.16%,对于我们测试过的一些应用而言,改进幅度更显著(提升幅度高达 30%)
- 降低应用启动时的功耗:平均降低 4.56%
- 相机启动速度更快:平均热启动速度加快 4.48%,冷启动速度平均加快 6.60%
- 缩短了系统启动时间:平均缩短了 1.5%(约 0.8 秒)
这些改进基于我们的初始测试,实际设备上的结果可能会有所不同。在继续测试的过程中,我们会进一步分析应用的潜在益处。
检查您的应用是否受到影响
如果您的应用使用任何原生代码,那么您应该重新构建应用以支持 16 KB 设备。如果您不确定自己的应用是否使用了原生代码,可以使用 APK 分析器确定是否存在任何原生代码,然后检查您找到的任何共享库的 ELF 段对齐情况。
如果您的应用仅使用以 Java 编程语言或 Kotlin 编写的代码(包括所有库或 SDK),那么您的应用已经支持 16 KB 设备。不过,我们建议您在 16 KB 环境中测试应用,以验证应用行为中没有意外回归。
您的应用是否使用了原生代码?
如果您的应用符合以下任一情况,则表明其使用了原生代码:
- 您的应用使用了任何 C/C++(原生)代码。如果您的应用使用 Android NDK,则表明您的应用使用了原生代码。
- 您的应用与使用这些库的任何第三方原生库或依赖项相关联。
- 您的应用由使用设备端原生库的第三方应用构建程序构建而成。
使用 APK 分析器识别原生库
APK 分析器是一款可用于对所构建的 APK 进行各方面评估的工具。如需确定您的应用是否使用原生代码或库,请按以下步骤操作:
- 打开 Android Studio,然后依次点击 File > Open,然后选择任意项目。
在菜单栏中,依次点击 Build > Analyze APK...
选择要分析的 APK。
查看
lib
文件夹,此文件夹中托管了共享对象 (.so
) 文件(如果存在)。如果存在任何共享对象文件,则表明您的应用使用了原生代码。如果没有共享对象文件或没有lib
文件夹,则表示您的应用不使用原生代码。
构建支持 16 KB 设备的应用
如需支持 16 KB 设备,使用原生代码的应用应完成以下部分中列出的步骤。如果您更新到 AGP 8.5.1 或更高版本和 NDK r28 或更高版本,并使用与 16 KB 兼容的预构建依赖项,则应用默认与 16 KB 兼容。
更新共享库的打包
我们建议您升级到 AGP 版本 8.5.1 或更高版本,并使用未压缩的共享库。
AGP 8.5.1 或更高版本
16 KB 设备要求随应用一起提供的未压缩共享库必须与 16 KB 的 ZIP 对齐边界对齐。为此,您需要升级到 Android Gradle 插件 (AGP) 8.5.1 或更高版本。如需详细了解升级流程,请参阅 Android Gradle 插件升级助理部分。
AGP 版本 8.5 或更低版本
如果您无法将 AGP 升级到 8.5.1 或更高版本,则可以改用压缩共享库。更新您的 Gradle 配置,以便 Gradle 在打包应用时压缩共享库,从而避免因共享库未对齐而导致应用安装问题。
Groovy
在 build.gradle
文件中,添加以下选项:
android {
...
packagingOptions {
jniLibs {
useLegacyPackaging true
}
}
}
Kotlin
在 build.gradle.kts
文件中,添加以下选项:
android {
...
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
}
使用 16 KB ELF 对齐编译您的应用
16 KB 设备要求共享库的 ELF 段使用 16 KB ELF 对齐方式正确对齐,才能运行应用。
如需使用 16 KB ELF 对齐编译您的应用,请根据您所使用的 Android NDK 版本完成以下某一部分中的步骤。
Android NDK r28 及更高版本
NDK 版本 r28 及更高版本默认编译为 16 KB 对齐。
Android NDK r27
如需支持使用 Android NDK 版本 r27 及更高版本编译 16 KB 对齐的共享库,您需要更新 ndk-build
、build.gradle
、build.gradle.kts
或链接器标志,如下所示:
ndk-build
在您的 Application.mk
中:
APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true
Groovy
在 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"
}
}
}
}
Kotlin
在 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
Android NDK r26 及更低版本
如需支持使用 Android NDK 版本 r26 或更低版本编译 16 KB 对齐的共享库,您需要按如下方式更新 ndk-build
或 cmake
配置:
ndk-build
更新 Android.mk
以启用 16 KB ELF 对齐:
LOCAL_LDFLAGS += "-Wl,-z,max-page-size=16384"
CMake
更新 CMakeLists.txt
以启用 16 KB ELF 对齐:
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384")
检查引用特定页面大小的代码实例
即使您的应用是 16 KB 对齐的,如果代码中的某些位置假定设备使用的是特定页面大小,您的应用也可能会遇到错误。为避免出现这种情况,请完成以下步骤:
移除引用
PAGE_SIZE
常量或假定设备页面大小为 4 KB (4096
) 的代码逻辑中的实例的任何硬编码依赖项。查找
mmap()
和其他需要页面对齐参数的 API 的用法,并在必要时替换为替代方案。
在某些情况下,如果您的应用使用 PAGE_SIZE
作为不与底层页面大小相关联的方便值,则在 16 KB 模式下使用时,这不会导致应用崩溃。但是,如果将此值通过 mmap
而非 MAP_FIXED
传递给内核,内核仍会使用整个页面,这会浪费一些内存。因此,在 NDK r27 及更高版本中启用 16 KB 模式时,PAGE_SIZE
将处于未定义状态。
如果您的应用以这种方式使用 PAGE_SIZE
,并且从不直接将此值传递给内核,请创建一个具有新名称的新变量,而不是使用 PAGE_SIZE
,以反映该变量用于其他用途,而不是反映实际的内存页。
在 16 KB 环境中测试应用
构建支持 16 KB 设备的应用后,您需要在 16 KB 环境中测试您的应用,以查看应用是否会遇到任何回归问题。为此,请按以下步骤操作:
设置以下任一测试环境:
启动测试设备,然后运行以下命令,验证设备是否使用的是 16 KB 环境:
adb shell getconf PAGE_SIZE
该命令应返回值
16384
。对于任何共享库,请验证共享库的 ELF 段是否使用 16 KB ELF 对齐方式正确对齐。您可以使用此脚本来帮助完成此过程:
#!/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
将脚本保存到文件(例如
alignment.sh
)中。解压缩应用的 APK 文件:
unzip APK_NAME.apk -d /tmp/my_apk_out ``` 1. Run the script on the extracted files in the `/tmp/my_apk_out` directory: ```none {: .devsite-terminal .devsite-click-to-copy } alignment.sh /tmp/my_apk_out | grep "arm64-v8a" ``` The script outputs either `ALIGNED` or `UNALIGNED` for all the `arm64-v8a` shared libraries. 1. If any `arm64-v8a` shared libraries are `UNALIGNED`, you'll need to [update the packaging for those libraries][20], then [recompile your app][21] and retest by following the steps in this section.
运行以下
zipalign
命令,验证您的应用是否按 16 KB 对齐,其中 APK_NAME 是应用的 APK 文件的名称:zipalign -c -P 16 -v 4 APK_NAME.apk
全面测试您的应用,重点关注更改引用特定页面大小的代码实例可能会影响的所有方面。
使用基于 16 KB 的 Android 15 系统映像设置 Android 模拟器
如需使用 Android 模拟器设置 16 KB 环境,请按以下步骤操作:
基于 16 KB 的 Android 15 模拟器系统映像与 Android Studio Jellyfish | 2023.3.1 或更高版本兼容。不过,为了在使用 Android 15 Beta 版时获得最佳体验,请下载 最新的预览版 Android Studio。
请注意,您可以保留已安装的现有 Android Studio 版本,因为您可以并行安装多个版本。
在 Android Studio 中,依次点击 Tools > SDK Manager。
在 SDK Platforms 标签页中,勾选 Show Package Details,然后展开 Android VanillaIceCream Preview 部分,根据您要创建的虚拟设备,选择以下一个或两个模拟器系统映像:
- Google APIs Experimental 16k Page Size ARM 64 v8a System Image
- Google API 实验性 16k 页面大小 Intel x86_64 Atom 系统映像
依次点击 Apply > OK 以下载您选择的任意系统映像。
按照相应步骤为 Android 15 设置虚拟设备,当系统提示您选择系统映像时,选择您下载的 16 KB 系统映像。如果系统未自动推荐,您可以在其他映像标签页中找到 16 KB 的系统映像。
- 在设备管理器中,点击 16 KB 映像旁边的三点状图标,然后点击在磁盘上显示。
- 在此文件夹中,找到
config.ini
文件。 将以下代码行添加到
config.ini
文件中,然后保存所做更改:kernel.parameters = androidboot.page_shift=14
如需验证更改,请运行以下命令,该命令应返回
16384
:adb shell getconf PAGE_SIZE
使用开发者选项在设备上启用 16 KB 模式
从 Android 15 QPR1 开始,您可以执行以下操作: 请使用 Google Play 提供的特定开发者选项 设备以 16 KB 模式启动设备,并执行设备端测试。
此开发者选项适用于以下设备:
- Pixel 8 和 Pixel 8 Pro(搭载 Android 15 QPR1 Beta 版 1 或更高版本)