支援 16 KB 網頁大小

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%
  • 縮短系統啟動時間:縮短 8% (平均約 950 毫秒)

這些改善項目是根據初步測試結果而來,實際裝置上的結果可能會有所不同。我們會在持續測試的過程中,針對應用程式可能獲得的效益提供額外分析。

確認應用程式是否受到影響

如果您的应用使用了任何原生代码,则应重新构建应用以支持 16 KB 设备。如果您不确定自己的应用是否使用了原生代码,可以使用 APK 分析器确定是否存在任何原生代码,然后检查您找到的任何共享库的 ELF 段对齐情况

如果您的应用仅使用以 Java 或 Kotlin 编程语言编写的代码(包括所有库或 SDK),则该应用已经支持 16 KB 设备。不过,我们建议您在 16 KB 环境中测试应用,以验证应用行为是否没有意外回归。

應用程式是否使用原生程式碼?

如果符合下列任一條件,即表示應用程式使用原生程式碼:

  • 應用程式使用任何 C/C++ (原生) 程式碼。如果應用程式使用 Android NDK,則表示應用程式使用原生程式碼。
  • 您的應用程式會連結使用這些程式庫或依附元件 (例如 SDK) 的任何第三方原生程式庫。
  • 應用程式是由使用裝置原生資料庫的第三方應用程式建構工具建構。

使用 APK 分析工具找出原生資料庫

APK 分析工具可用來多方評估已建構的 APK。如要判斷應用程式是否使用原生程式碼或程式庫,請按照下列步驟操作:

  1. 開啟 Android Studio,然後依序點選「File」>「Open」,然後選擇任何專案。
  2. 在選單列中,依序按一下「Build」>「Analyze APK...」

    用於啟動 APK 分析工具的 Studio 建構選單選項

  3. 選擇要分析的 APK。

  4. 查看 lib 資料夾,查看有否代管共用物件 (.so) 檔案。如果有任何共用物件檔案,表示應用程式使用原生程式碼。如果沒有共用物件檔案或 lib 資料夾,則表示應用程式未使用原生程式碼。

    APK 分析工具檢視畫面,顯示共用物件檔案

檢查共用程式庫的 ELF 區段對齊

針對任何共用程式庫,請確認共用程式庫的 ELF 區段是否已使用 16 KB ELF 對齊方式正確對齊。如果您在 Linux 或 macOS 上進行開發,可以按照下一個部分所述使用 check_elf_alignment.sh 指令碼。您也可以直接使用指令列工具

使用 check_elf_alignment.sh 指令碼 (Linux 或 macOS)

請按照下列步驟,使用 check_elf_alignment.sh 指令碼檢查 ELF 區段的對齊方式:

  1. check_elf_alignment.sh 指令碼儲存到檔案中。

  2. 在應用程式的 APK 檔案上執行指令碼:

    check_elf_alignment.sh APK_NAME.apk
    

    指令碼會針對所有 arm64-v8a 共用程式庫輸出 ALIGNEDUNALIGNED

  3. 如果任何 arm64-v8ax86_64 共用資料庫為 UNALIGNED,您就需要更新這些程式庫的封裝,然後重新編譯應用程式,並按照本節中的步驟進行重新測試。

直接使用指令列工具

如要直接使用指令列工具檢查 ELF 區段的對齊情形,請按照下列步驟操作:

  1. 請確認已使用 Android Studio 中的 SDK Managersdkmanager 指令列工具,安裝 Android SDK Build-Tools 35.0.0 以上版本和 Android NDK。
  2. 解壓縮應用程式的 APK 檔案:

    Linux 或 macOS

    unzip APK_NAME.apk -d /tmp/my_apk_out
    

    Windows (PowerShell)

    Expand-Archive -Path .\APK_NAME.apk -DestinationPath ~\tmp\my_apk_out
    
  3. 在您用來解壓縮 APK 檔案的暫時目錄中,檢查 lib 目錄的內容,找出共用物件 (.so) 檔案。這些是使用 APK 分析工具找出原生資料庫時,您會看到的共用物件檔案。針對每個共用物件檔案執行下列指令:

    Linux 或 macOS

    SDK_ROOT_LOCATION/Android/sdk/ndk/NDK_VERSION/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-objdump -p SHARED_OBJECT_FILE.so | grep LOAD
    

    Windows (PowerShell)

    SDK_ROOT_LOCATION\Android\sdk\ndk\NDK_VERSION\toolchains\llvm\prebuilt\windows-x86_64\bin\llvm-objdump.exe -p SHARED_OBJECT_FILE.so | Select-String -Pattern "LOAD"
    

    其中 SDK_ROOT_LOCATION 是您安裝 Android SDK 的目錄路徑、SHARED_OBJECT_FILE 是您要檢查的共用物件檔案名稱,而 NDK_VERSION 則是您安裝的 Android NDK 版本 (例如 28.0.12433566)。對於您檢查的每個檔案,輸出內容會類似以下:

    LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**14
    LOAD off    0x0000000000042a90 vaddr 0x0000000000043a90 paddr 0x0000000000043a90 align 2**14
    LOAD off    0x0000000000046230 vaddr 0x0000000000048230 paddr 0x0000000000048230 align 2**14
    
  4. 檢查輸出行,確認負載區段的值不小於 2**14。如果任何載入區段的值為 2**132**12 或更低,您就需要更新這些程式庫的封裝內容,然後重新編譯應用程式,並按照本節中的步驟進行重新測試。

  5. 接下來,請在應用程式的 APK 檔案上執行 zipalign 指令列工具:

    Linux 或 macOS

    SDK_ROOT_LOCATION/Android/sdk/build-tools/35.0.0/zipalign -v -c -P 16 4 APK_NAME.apk
    

    Windows (PowerShell)

    SDK_ROOT_LOCATION\Android\sdk\build-tools\35.0.0\zipalign.exe -v -c -P 16 4 APK_NAME.apk
    

    其中 SDK_ROOT_LOCATION 是安裝 Android SDK 的目錄路徑,APK_NAME 則是應用程式 APK 檔案的名稱。如果所有共用程式庫都已正確對齊,輸出內容的最後一行會顯示「驗證成功」。

    如果驗證失敗,部分共用程式庫就需要重新對齊,因此您必須更新這些程式庫的封裝內容,然後重新編譯應用程式,並按照本節的步驟重新測試。

建構支援 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 裝置需要使用 16 KB ELF 對齊方式,正確對齊共用程式庫的 ELF 區段,才能執行應用程式。

如要使用 16 KB ELF 對齊方式編譯應用程式,請根據您使用的 Android NDK 版本,完成下列任一節中的步驟。

Android NDK r28 以上版本

NDK 28 以上版本預設會編譯 16 KB 對齊。

Android NDK r27

如要支援使用 Android NDK 7 以上版本編譯 16 KB 對齊共用程式庫,您必須更新 ndk-buildbuild.gradlebuild.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-buildcmake 設定,如下所示:

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,如果程式碼中某處假設裝置使用特定的頁面大小,應用程式仍可能發生錯誤。如要避免這種情況,請完成下列步驟:

  1. 移除任何硬式編碼的依附元件,這些依附元件會參照 PAGE_SIZE 常數或程式碼邏輯中的例項,並假設裝置的頁面大小為 4 KB (4096)。

    請改用 getpagesize()sysconf(_SC_PAGESIZE)

  2. 找出需要使用與頁面對齊的引數的 mmap() 和其他 API 用法,並視需要以其他方法取代。

在某些情況下,如果應用程式使用 PAGE_SIZE 做為方便的值,且未與基礎頁面大小綁定,則在 16 KB 模式下使用時,不會導致應用程式中斷。不過,如果這個值是透過 mmap 傳遞至核心,而沒有 MAP_FIXED,核心仍會使用整個頁面,這會浪費一些記憶體。因此,在 NDK r27 以上版本中啟用 16 KB 模式時,PAGE_SIZE 會未定義。

如果應用程式以這種方式使用 PAGE_SIZE,且從未直接將此值傳遞至核心,請不要使用 PAGE_SIZE,而是建立具有新名稱的新變數,以反映該變數用於其他用途,而非用於實際的記憶體頁面。

檢查 SDK 是否支援 16 KB

許多 SDK 都支援 16 KB 的分頁大小,尤其是您自行建構或取得近期預先建構的 SDK 時。不過,由於部分 SDK 預先建構或 SDK 版本不支援 16 KB,因此您應查看各個 SDK 供應商的網站,判斷應使用哪個版本來支援 16 KB。

在 16 KB 環境中測試應用程式

在建構支援 16 KB 裝置的應用程式後,您應該在 16 KB 環境中測試應用程式,看看應用程式是否發生任何回歸現象。如要採用這種方式,請按照下列步驟進行:

  1. 設定 Android 15 SDK

  2. 設定下列其中一個測試環境:

  3. 啟動測試裝置,然後執行下列指令,確認裝置使用 16 KB 環境:

    adb shell getconf PAGE_SIZE
    

    這個指令應傳回 16384 值。

  4. 執行下列 zipalign 指令,確認應用程式是否已對齊 16 KB,其中 APK_NAME 是應用程式 APK 檔案的名稱:

    zipalign -c -P 16 -v 4 APK_NAME.apk
    
  5. 請徹底測試應用程式,並著重於變更參照特定頁面大小的程式碼例項可能受到影響的任何部分。

使用 16 位元 Android 15 系統映像檔設定 Android Emulator

如要使用 Android Emulator 設定 16 KB 環境,請按照下列步驟操作:

  1. 以 16 千位元為基礎的 Android 15 模擬器系統映像檔與 Android Studio Jellyfish | 2023.3.1 以上版本相容。不過,如要獲得最佳的 Android 15 Beta 版使用體驗,請下載 Android Studio 的最新預先發布版

    請記住,您可以保留現有的 Android Studio 版本,因為您可以同時安裝多個版本

  2. 在 Android Studio 中,按一下「Tools」(工具) >「SDK Manager」。

  3. 在「SDK Platforms」分頁中,勾選「Show Package Details」,然後展開「Android VanillaIceCream Preview」部分,並選取下列模擬器系統映像檔之一或兩者,視您要建立的虛擬裝置而定:

    • Google APIs 實驗性 16k 頁面大小 ARM 64 8a 版系統映像檔
    • Google API 實驗性 16k 頁面大小 Intel x86_64 Atom 系統映像檔

    使用 Android Studio 中的 SDK Manager 下載 16 KB 模擬器系統映像檔

  4. 依序按一下「Apply」>「OK」,即可下載所選的系統映像檔。

  5. 請按照這篇文章的步驟設定 Android 15 的虛擬裝置,當系統提示您選取系統映像檔時,請選取您下載的 16 KB 系統映像檔。如果系統未自動建議,您可以在「Other Images」分頁中找到 16 KB 的系統映像檔。

    在「其他圖片」分頁中尋找 16 KB 模擬器圖片

  1. 在裝置管理工具中,按一下 16 KB 圖片旁的 3 點圖示,然後按一下「Show on Disk」
  2. 在這個資料夾中,找出 config.ini 檔案。
  3. config.ini 檔案中新增下列程式碼行,然後儲存變更:

    kernel.parameters = androidboot.page_shift=14
    
  4. 如要確認變更,請執行下列指令,應該會傳回 16384

    adb shell getconf PAGE_SIZE
    

使用開發人員選項在裝置上啟用 16 KB 模式

切換「使用 16 KB 頁面大小啟動」開發人員選項 這個選項可讓裝置啟動 16 KB 模式。

從 Android 15 QPR1 開始,你可以: 使用開發人員選項 裝置以 16 KB 模式啟動裝置,並執行裝置端測試。

這個開發人員選項適用於下列裝置:

  • Pixel 8 和 8 Pro (搭載 Android 15 QPR1 Beta 1 以上版本)