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 分析器来确定是否存在任何原生代码。
如果您的应用仅使用以 Java 编程语言或 Kotlin 编写的代码(包括所有库或 SDK),那么该应用已经支持 16 KB 设备。不过,我们建议您在 16 KB 的环境中测试应用,以确认应用行为是否存在意外回归问题。
您的应用是否使用了原生代码?
如果符合以下任一条件,则您的应用会使用原生代码:
- 您的应用使用了任何 C/C++(原生)代码。如果您的应用使用的是 Android NDK,那么应用将使用原生代码。
- 您的应用会与任何第三方原生库或依赖项相关联, 使用它们。
- 您的应用由第三方应用构建程序构建,该构建程序使用 设备。
使用 APK 分析器识别原生库
APK 分析器是一款工具,可让您评估 build 的各个方面 APK。如需确定您的应用使用的是原生代码还是库,请按照以下提示操作 步骤:
- 打开 Android Studio,然后依次点击 File >打开并选择任意项目。
从菜单栏中,点击 Build >分析 APK...
选择要分析的 APK。
查看
lib
文件夹,此文件夹中托管了共享对象 (.so
) 文件(如有) 。如果存在任何共享对象文件,您的应用将使用原生 代码。如果不存在共享对象文件或没有lib
文件夹, 那么您的应用就不会使用原生代码。
构建支持 16KB 设备的应用
要支持 16 KB 设备,使用原生代码的应用应完成 具体步骤如下。
更新共享库的打包
我们建议您升级到 AGP 版本 8.3 或更高版本,并使用未压缩的 共享库。
AGP 版本 8.3 或更高版本
16 KB 设备要求附带未压缩共享库的应用 在 16 KB 压缩对齐边界上对齐。为此,您需要升级 Android Gradle 插件 (AGP) 8.3 或更高版本。请参阅 Android Gradle 插件升级助理部分,详细了解升级流程。
AGP 版本 8.2 或更低版本
如果您无法将 AGP 升级到版本 8.3 或更高版本,则替代方案是 改用压缩的共享库。将 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 r26 及更低版本
支持使用 Android NDK 编译 16 KB 对齐的共享库
版本 r26 或更低版本,则需要更新 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")
Android NDK r27 及更高版本
支持使用 Android NDK 编译 16 KB 对齐的共享库
版本 r27 及更高版本,则需要更新 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
检查引用特定页面大小的代码实例
即使您的应用是 16 KB 对齐的,如果将 会假定设备使用的是特定的页面大小。为了避免这种情况 请完成以下步骤:
移除所有引用
PAGE_SIZE
的硬编码依赖项 常量或实例,它假定设备的页面 大小为 4 KB (4096
)。查看是否使用了
mmap()
和其他需要页面对齐的 API 参数,并在必要时替换为替代参数。
在某些情况下,如果您的应用将 PAGE_SIZE
作为一个不方便使用的值,
与底层页面大小相关联,那么这不会导致应用中断
当在 16 KB 模式下使用时。不过,如果将该值传递给内核,
对于不带 MAP_FIXED
的 mmap
,内核仍会使用整个页面,
会浪费一些内存因此,当大小为 16 KB 时,未定义 PAGE_SIZE
。
模式在 NDK r27 及更高版本中启用。
如果您的应用以这种方式使用 PAGE_SIZE
,并且从未将此值直接传递给
则不使用 PAGE_SIZE
,而是创建一个具有新变量的新变量
表明相应信息已用于其他用途,并不反映真实情况
内存页。
在 16 KB 的环境中测试您的应用
在构建支持 16KB 设备的应用后,您需要 在 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
运行以下
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 中,依次点击 Tools > SDK Manager。
在 SDK Platforms 标签页中,选中 Show Package Details,然后展开 Android VanillaIceCream Preview 部分,然后选择 以下模拟器系统映像,具体取决于您要创建的虚拟设备 创建:
- Google API 实验性 16k 页面大小 ARM 64 v8a 系统映像
- Google API 实验性 16k 页面大小 Intel x86_64 Atom 系统映像
点击应用 >确定以下载您选择的任何系统映像。
按照相关步骤针对 Android 15 设置虚拟设备,以及何时 根据提示选择系统映像,请选择 。如果系统未自动推荐该内容,您可以 Other Images 标签页中的 16 KB 系统映像。
- 在设备管理器中,点击 16 KB 图片旁边的 3 个点,然后点击 在磁盘上显示。
- 在此文件夹中,找到
config.ini
文件。 将以下代码行添加到
config.ini
文件中并保存更改:kernel.parameters = androidboot.page_shift=14
如需验证您的更改,请运行以下命令,该命令应该会返回
16384
:adb shell getconf PAGE_SIZE