適配Android 15 的 16 KB PAGE SIZE
2025/11/1起,上架gp針對的Android 15+裝置的app需支援16kb page size

如何驗證app是否符合16kb page size的要求
把 .aar
上傳到 gcp後台
後,可以看到網頁下面會幫你檢查
(目前上架還沒有強制要求,估計是讓你提早檢查)

可以看到若是沒有達成會有This app version only targets 32 bit devices and does not need to support 16 KB
提示
官方推薦方法用cmd zipalign
驗證.so對齊與否
使用指令:
zipalign -c -P 16 -v 4 APK_NAME.apk
若通過會顯示驗證成功
將你的apk
拖移到Android Studio的視窗中
他幫會幫你解析你的apk
例如下圖,在x86_64
會顯示未對齊:


#!/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
用腳本
去檢查build cache資料夾下的.so 在各ABI下的表現
在這個資料夾下用這個腳本,(或者你有其他自定義.so的資料夾下):
..//Your Project Name/Your Project modele/build/intermediates/stripped_native_libs/channelDebug/stripChannelDebugDebugSymbols/out/lib
armeabi
armeabi-v7a
x86
arm64-v8a
x86_64
這個算是多給自己上一層保險
或者一開始想簡單測試的時候
可以直接把app安裝到 16 kb page size的模擬器
在Android Studio中AVD裡面應該可以找到
(不過模擬器是依序執行 解決完一項才會出現下一樣)
例如:把app run on 16 KB page size devices 遇到某個.so
crash問題:
會發現就算用了官方推薦的方法
或是手動把apk丟進AS中去驗證
還是有機會遇到畫面上顯示成功
但用另一個方法卻顯示不同結果的可能
這邊我記錄下來
大家可以參考:
-
用
zipalign
指令,-P 設定16
驗證都顯示是成功,但實際在其他方法測試可能不成功
-
AS內建
分析器
在不同ABI下,有不同的對齊程度
不過實測修改mmkv調整成支援16KB的版本後
再次丟入分析器還是顯示出mmkv 未對齊
但實際run在16KB模擬器上已經不會crash
或者用腳本
去跑也顯示已對齊 -
使用
腳本
去看ELF有沒有對齊2^14 || 2^16
不同ABI架構下 可能會有不同對齊的程度
但這個就要看官方最終要求的是哪些要對齊就好
因為目前比較主流應該就是x86_64
跟arm64-v8a
GCP後台的驗證目前試起來也只有針對這兩個ABI去驗證
(也可以未來官方有要求的話,在針對每個ABI優化,否則為了上架就先優化該優化的就可以)
後記:記錄我有遇到過的第三方lib內的.so未對齊的例子
mmkv
- Crash log
Process: com.xxx.xxxxxxxxx, PID: 5910
java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH/DT_GNU_HASH in "/data/app/~~GDguKzQkEWWU7nKgxukJ3g==/com.xxx.xxxxxxxx-LLLvOX6N3NINoK5qFkhyxQ==/base.apk!/lib/arm64-v8a/libmmkv.so" (new hash type from the future?)
-
解決方法:
方法1
. 去官方github 修改相關設定後自行Build一個16kb版本的.aar 之後把原本的implment的地方改成自己build的內容方法2
. 升級到1.3.14
版本,實測後可以正常運行方法3
. 官方Oct 22, 2024
更新了2.0.0
支援16KB 將相關引用更新到2.0.0以上
參考官方release note
sqlcipher
- Crash log
pid: 8796, tid: 8891, name: pool 1 >>> com.xxx.xxxxxxxxxx <<<
2025-05-21 14:29:47.380 8901-8901 DEBUG pid-8901 A #02 pc 0000000000006700 /data/app/~~p4bSI2XwdSmTfm3vZluhdw==/com.sand.airdroidkidp-9wKFuA4x7Jclg5hVTLRBSA==/base.apk!libtnet-3.1.14.so (offset 0x5504000) (BuildId: 2510ff56a9673370b9d664c21a3dcb04a541d939)
2025-05-21 14:29:47.380 8901-8901 DEBUG pid-8901 A #03 pc 00000000000060c4 /data/app/~~p4bSI2XwdSmTfm3vZluhdw==/com.sand.airdroidkidp-9wKFuA4x7Jclg5hVTLRBSA==/base.apk!libtnet-3.1.14.so (offset 0x5504000) (JNI_OnLoad+76) (BuildId: 2510ff56a9673370b9d664c21a3dcb04a541d939)
解決方法
:遷移到新版本
官方github repo: sqlcipher-android
遷移文件:點此
xCrash
-
遇到此問題的log
2025-06-03 11:14:11.095 6505-6505 xcrash com.xxx.xxxxxx E NativeHandler System.loadLibrary failed (Ask Gemini) java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH/DT_GNU_HASH in "/data/app/~~NKxgZmiW0fnAnkqxbM6pmg==/com.xxxxxx.xxxxx-TBH_eXBREJRiwzaa0oJFsQ==/base.apk!/lib/arm64-v8a/libxcrash.so" (new hash type from the future?)
-
實測
解決方法
,自行build aar出來-
clone專案 :Github repo
-
把專案內的
CMakeList.txt
中 加入 2^14 || 2^16 MaxSize的相關字段,如: -
安裝ndk相關環境,原專案是用
21.3.6528147
,我本地安裝後出現build failed, 所以嘗試一個接近的版本
-
-
NDK安裝方式
- 列出已安裝NDK
ls -la ~/Library/Android/sdk/ndk/
- 檢查已安裝NDK目標版本是否能正常build
~/Library/Android/sdk/ndk/[your_version]/ndk-build --version
- 查看可下載版本
~/Library/Android/sdk/tools/bin/sdkmanager --list | grep ndk
- 安裝指定ndk
~/Library/Android/sdk/tools/bin/sdkmanager --install "ndk;25.2.9519653"
其中有可能因為jdk版本太新無法下載,把環境中jdk
切回8即可下載
- 開始build xCrash 的.aar, 下方指令主要執行 clean > build > checkstyle 可自行搭配 主要是執行build 但調配過程中,遇到build failed 可以拿來檢查看看
./gradlew clean :xcrash_lib:build -x checkstyle --rerun-tasks
-
可能遇到的問題
- 用
./gradlew :xcrash_lib:build
時遇到:,就算沒打checkstyle
,他還是run了checkstyle,其檢查到AnrHandler.java
中的java if 少了個空格,不過原始clone下來就是這樣,後來把空格加入即可
> Task :xcrash_lib:checkstyle FAILED [ant:checkstyle] [ERROR] ../xcrash/AnrHandler.java:144:9: 'if' is not followed by whitespace. [WhitespaceAfter]
- 用
-
把.aar 替換掉原本的xCrash即可,
替換後
雖然用寫好的./agliment.sh 檢查顯示已經對齊
但
實際上在16kb裝置上還是有報錯
-
Workaround方法
- 因為要實測能不能在16 kb pages size裝置上run,但其不會上在google play concole,所以可以把build config切換到 intl 測試即可
- 因為要實測能不能在16 kb pages size裝置上run,但其不會上在google play concole,所以可以把build config切換到 intl 測試即可
Umeng
- 遇到 libtnet.so crash問題
- 不過他也不會上到gpc,所以這邊也可以用 Workaround來測試,切換到intl來build
AMap aka 高德地圖
-
用
implementation
方式的把amap
導入
接著做16KB檢查../str/c/stripChannelDebugDebugSymbols/out/lib
會發現 未對齊
-
改用
官網
下載的最新版sdk嘗試 等於是改成用.jar
成功可以build且run到16 kb page size裝置上
- 重新檢查
../str/c/stripChannelDebugDebugSymbols/out/lib
下的.so
發現消失了但直接檢查官網給的
.so
還是未對齊 (這個是下載下來的.zip解壓縮後)或者直接用官網的.aar 解出裡面包的.so 也未對齊
- 重新檢查
-
目前查看mvn最新的amap版本,尚未有官網上的最新版本
-
也沒發現有開源source code
-
在16 kb page size上會遇到
-
後續發現這個自己無法自己解決,因為官方沒有開源source code,無法透過自己build來製作workaround 所以只能等待官方更新了