Google Play 要求所有应用在 2026 年 5 月 31 日前完成 16 KB 内存页面大小适配。本文记录完整的检测与适配流程。

1. 背景

Android 15 引入了 16 KB 内存页面对齐要求,Google Play 强制要求应用中的所有 .so 文件满足以下三个条件:

  1. PT_LOAD segment 对齐 >= 16 KB
  2. RELRO 段必须位于 segment 末尾(suffix)
  3. RELRO 段末尾必须 16 KB 对齐

官方文档:Android 页面大小适配指南


2. 检测方法

2.1 方法一:NDK 工具手动检测

解压 APK 取出 .so 文件,使用 NDK 自带的 llvm-objdump 工具检测(必须用 PowerShell,cmd 不支持管道过滤):

llvm-objdump.exe -p E:\Test\so\arm64-v8a\libanogs.so | Select-String -Pattern "LOAD"

查看输出中 LOAD 行末尾的对齐值:

  • 2**14(即 16384)及以上 ✅ 合规
  • 2**12(4096)或 2**13(8192)❌ 不合规

工具路径:{YourNDKPath}\toolchains\llvm\prebuilt\windows-x86_64\bin

注意:此方法只检测 PT_LOAD,不检测 RELRO。


2.2 方法二:Google 官方脚本检测

Google 提供了完整的 ELF 对齐检测脚本,可同时检测 PT_LOAD 和 RELRO:

脚本地址:check_elf_alignment.sh

check_elf_alignment.sh APK_NAME.apk

2.3 方法三:Android Studio APK Analyzer

将 Android Studio 升级到最新版本,使用内置的 APK Analyzer 功能即可可视化检测。

常见报错信息:

# PT_LOAD 不合规
4 KB LOAD section alignment, but 16 KB is required

# RELRO 不合规
RELRO is not a suffix and its end is not 16 KB aligned

3. 适配方法

3.1 Unity 相关 .so

Unity 引擎生成的 .so 不合规时,需要升级 Unity 编辑器版本来解决,无法手动修改。

升级后若 C++ 代码没有重新导出,可以删除以下缓存目录强制重新生成:

Library/Bee/
Library/il2cpp_*/

3.2 第三方 SDK 的 .so

联系 SDK 提供商升级至合规版本。若提供商无法及时支持,应考虑移除该 SDK。

3.3 自行用 NDK 编译的 .so

升级 NDK 并添加链接参数

在编译命令中增加 max-page-sizecommon-page-size 参数:

{NDK Path}/ndk-build ^
NDK_PROJECT_PATH=. ^
APP_BUILD_SCRIPT=Android.mk ^
NDK_APPLICATION_MK=Application.mk ^
APP_ABI="armeabi-v7a x86 arm64-v8a x86_64" ^
APP_LDFLAGS="-Wl,-z,max-page-size=16384 -Wl,-z,common-page-size=16384"

修改 Android.mk

Android.mk 中增加以下链接标志,确保 RELRO 对齐:

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

修改 Application.mk

1. 移除 cmd-strip 调用

NDK r23+ 中 strip 工具路径改为 LLVM 版本,旧的 cmd-strip 路径会报错。新版 NDK 会自动调用 strip,直接删除该行即可。

2. 替换 STL 类型

# 旧(已废弃)
APP_STL := gnustl_static

# 改为
APP_STL := c++_static

补充缺失的 PAGE_SIZE 宏

NDK 新版本不再提供 PAGE_SIZE / PAGE_MASK 宏,若代码中有使用,需手动定义:

#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif

#ifndef PAGE_MASK
#define PAGE_MASK (~(PAGE_SIZE - 1))
#endif