KC Blog

適配Android 15 的 16 KB PAGE SIZE

10 min read
Android#Android#Kotlin

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

mcp 原文

如何驗證app是否符合16kb page size的要求

方法1: gpc檢查方法

.aar 上傳到 gcp後台後,可以看到網頁下面會幫你檢查
(目前上架還沒有強制要求,估計是讓你提早檢查)

mcp

可以看到若是沒有達成會有This app version only targets 32 bit devices and does not need to support 16 KB提示 mcp

方法2: zipalign

官方推薦方法用cmd zipalign驗證.so對齊與否
使用指令: zipalign -c -P 16 -v 4 APK_NAME.apk
若通過會顯示驗證成功 mcp


方法3: AS中的分析器

將你的apk 拖移到Android Studio的視窗中
他幫會幫你解析你的apk
例如下圖,在x86_64會顯示未對齊:

未對齊範例1
mcp mcp
方法4: 寫腳本檢查so是否對齊16kb
#!/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 mcp armeabi-v7a mcp x86 mcp

arm64-v8a mcp

x86_64 mcp


方法5: 模擬器驗證16KB PAGE SIZE是否會Crash

這個算是多給自己上一層保險
或者一開始想簡單測試的時候
可以直接把app安裝到 16 kb page size的模擬器
在Android Studio中AVD裡面應該可以找到
(不過模擬器是依序執行 解決完一項才會出現下一樣)

例如:把app run on 16 KB page size devices 遇到某個.so crash問題: mcp


透過上面的方法可能會遇到的情況
因為在實驗過程中
會發現就算用了官方推薦的方法
或是手動把apk丟進AS中去驗證
還是有機會遇到畫面上顯示成功
但用另一個方法卻顯示不同結果的可能
這邊我記錄下來
大家可以參考:
  1. zipalign指令,-P 設定16
    驗證都顯示是成功,但實際在其他方法測試可能不成功
    mcp mcp

  2. AS內建分析器
    在不同ABI下,有不同的對齊程度
    不過實測修改mmkv調整成支援16KB的版本後
    再次丟入分析器還是顯示出mmkv 未對齊
    但實際run在16KB模擬器上已經不會crash
    或者用腳本去跑也顯示已對齊

  3. 使用腳本去看ELF有沒有對齊2^14 || 2^16
    不同ABI架構下 可能會有不同對齊的程度
    但這個就要看官方最終要求的是哪些要對齊就好
    因為目前比較主流應該就是x86_64arm64-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)

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的相關字段,如: mcp mcp

    • 安裝ndk相關環境,原專案是用21.3.6528147 ,我本地安裝後出現build failed, 所以嘗試一個接近的版本 mcp

  • 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 檢查顯示已經對齊 mcp實際上在16kb裝置上還是有報錯

  • Workaround方法

    • 因為要實測能不能在16 kb pages size裝置上run,但其不會上在google play concole,所以可以把build config切換到 intl 測試即可 mcp

Umeng

  • 遇到 libtnet.so crash問題
  • 不過他也不會上到gpc,所以這邊也可以用 Workaround來測試,切換到intl來build mcp

AMap aka 高德地圖

  • implementation方式的把amap導入
    接著做16KB檢查../str/c/stripChannelDebugDebugSymbols/out/lib

    mcp 會發現 未對齊 mcp
  • 改用 官網 下載的最新版sdk嘗試 等於是改成用.jar mcp mcp mcp 成功可以build且run到16 kb page size裝置上

    • 重新檢查 ../str/c/stripChannelDebugDebugSymbols/out/lib下的.so 發現消失了 mcp 但直接檢查官網給的.so 還是未對齊 (這個是下載下來的.zip解壓縮後) mcp 或者直接用官網的.aar 解出裡面包的.so 也未對齊 mcp
  • 目前查看mvn最新的amap版本,尚未有官網上的最新版本

  • 也沒發現有開源source code

  • 在16 kb page size上會遇到 mcp

  • 後續發現這個自己無法自己解決,因為官方沒有開源source code,無法透過自己build來製作workaround 所以只能等待官方更新了

相關文章

基於標籤和分類推薦的相關內容

5 min read

掌握 Android 持久化存儲:Kotlin 與 Room 資料庫實戰教學

在這篇實戰教學中,我們將深入探討如何在 Android 應用程式中使用 Kotlin 與 Room 來實現持久化存儲。無論你是初學者還是有經驗的開發者,這篇教學都將為你提供實用的知識和技巧,讓你能夠更有效地開發 Android 應用程式。讓我們一起探索 Kotlin 與 Room 資料庫的強大功能,並將它們完美地融入到你的下一個 Android 項目中吧!

📁 AndroidDev
#Android#Kotlin