پشتیبانی از اندازه صفحه 16 کیلوبایت

از لحاظ تاریخی، اندروید تنها از اندازه صفحات حافظه 4 کیلوبایتی پشتیبانی می‌کند که عملکرد حافظه سیستم را برای میانگین کل حافظه‌ای که دستگاه‌های اندرویدی معمولا دارند بهینه می‌کند. با شروع Android 15، AOSP از دستگاه هایی پشتیبانی می کند که برای استفاده از اندازه صفحه 16 کیلوبایت (دستگاه های 16 کیلوبایت) پیکربندی شده اند. اگر برنامه شما از کتابخانه های NDK استفاده می کند، چه به طور مستقیم یا غیرمستقیم از طریق یک SDK، باید برنامه خود را بازسازی کنید تا بتواند روی این دستگاه های 16 کیلوبایتی کار کند.

از آنجایی که سازندگان دستگاه‌ها به ساخت دستگاه‌هایی با حافظه فیزیکی (RAM) بیشتر ادامه می‌دهند، بسیاری از این دستگاه‌ها از اندازه صفحه ۱۶ کیلوبایت (و در نهایت بیشتر) برای بهینه‌سازی عملکرد دستگاه استفاده می‌کنند. افزودن پشتیبانی برای دستگاه‌های اندازه صفحه 16 کیلوبایت، برنامه شما را قادر می‌سازد تا در این دستگاه‌ها اجرا شود و به برنامه شما کمک می‌کند از بهبودهای عملکرد مرتبط بهره مند شود. بدون کامپایل مجدد، برنامه‌ها ممکن است در دستگاه‌های 16 کیلوبایتی در نسخه‌های بعدی اندروید تولید نشوند.

برای کمک به اضافه کردن پشتیبانی از برنامه خود، راهنمایی هایی در مورد نحوه بررسی اینکه آیا برنامه شما تحت تأثیر قرار گرفته است ، نحوه بازسازی برنامه خود (در صورت وجود) و نحوه آزمایش برنامه خود در یک محیط 16 کیلوبایتی با استفاده از شبیه سازها (از جمله Android) ارائه کرده ایم. 15 تصویر سیستم برای شبیه ساز اندروید).

مزایا و دستاوردهای عملکرد

配置为 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 Analyzer شناسایی کنید

APK Analyzer ابزاری است که به شما امکان می دهد جنبه های مختلف یک APK ساخته شده را ارزیابی کنید. برای تشخیص اینکه آیا برنامه شما از کد بومی یا کتابخانه‌ها استفاده می‌کند، این مراحل را دنبال کنید:

  1. Android Studio را باز کنید، سپس روی File > Open کلیک کنید و هر پروژه را انتخاب کنید.
  2. از نوار منو، روی Build > Analyze APK کلیک کنید...

    گزینه منوی Studio Build برای راه اندازی APK Analyzer

  3. APK مورد نظر برای تجزیه و تحلیل را انتخاب کنید.

  4. به داخل پوشه lib نگاه کنید، که در صورت وجود فایل‌های شی اشتراک‌گذاری شده ( .so ) را میزبانی می‌کند. اگر هر فایل شی مشترکی وجود دارد، برنامه شما از کد بومی استفاده می کند. اگر هیچ فایل شی مشترکی وجود ندارد یا پوشه lib وجود ندارد، برنامه شما از کد بومی استفاده نمی کند.

    نمای APK Analyzer که نشان می‌دهد فایل‌های شی اشتراک‌گذاری شده وجود دارد

برنامه خود را با پشتیبانی از دستگاه های 16 کیلوبایتی بسازید

برای پشتیبانی از دستگاه‌های 16 کیلوبایتی، برنامه‌هایی که از کد بومی استفاده می‌کنند باید مراحلی را که در بخش‌های زیر توضیح داده شده است انجام دهند.

بسته بندی کتابخانه های مشترک خود را به روز کنید

توصیه می کنیم به نسخه 8.3 یا بالاتر AGP ارتقا دهید و از کتابخانه های اشتراکی فشرده نشده استفاده کنید.

AGP نسخه 8.3 یا بالاتر

دستگاه‌های 16 کیلوبایتی به برنامه‌هایی نیاز دارند که با کتابخانه‌های اشتراک‌گذاری‌شده فشرده‌نشده ارسال شوند تا آن‌ها را روی یک مرز زیپ تراز شده 16 کیلوبایتی تراز کنند. برای انجام این کار، باید به Android Gradle Plugin (AGP) نسخه 8.3 یا بالاتر ارتقا دهید. برای جزئیات بیشتر در مورد فرآیند ارتقا، به بخش ارتقاء پلاگین Android Gradle مراجعه کنید.

AGP نسخه 8.2 یا پایین تر

اگر نمی توانید AGP را به نسخه 8.3 یا بالاتر ارتقا دهید، گزینه جایگزین استفاده از کتابخانه های اشتراکی فشرده شده است. پیکربندی Gradle خود را به‌روزرسانی کنید تا Gradle کتابخانه‌های مشترک شما را هنگام بسته‌بندی برنامه‌تان فشرده کند تا از مشکلات نصب برنامه با کتابخانه‌های به اشتراک‌گذاشته‌نشده اجتناب شود.

شیار

در فایل build.gradle خود گزینه زیر را اضافه کنید:

android {
  ...
  packagingOptions {
      jniLibs {
        useLegacyPackaging true
      }
  }
}

کاتلین

در فایل build.gradle.kts خود گزینه زیر را اضافه کنید:

android {
  ...
  packagingOptions {
      jniLibs {
        useLegacyPackaging = true
      }
  }
}

برنامه خود را با استفاده از تراز ELF 16 کیلوبایتی کامپایل کنید

دستگاه‌های 16 کیلوبایتی نیاز دارند که بخش‌های ELF کتابخانه‌های مشترک با استفاده از ترازبندی ELF 16 کیلوبایتی به درستی تراز شوند تا برنامه شما اجرا شود.

برای کامپایل برنامه خود با استفاده از تراز 16 کیلوبایتی ELF، بسته به نسخه Android NDK که استفاده می‌کنید، مراحل یکی از بخش‌های زیر را تکمیل کنید.

اندروید NDK r26 و پایین تر

برای پشتیبانی از کامپایل کتابخانه های اشتراکی تراز شده با ۱۶ کیلوبایت با Android NDK نسخه r26 یا پایین تر، باید پیکربندی ndk-build یا cmake خود را به صورت زیر به روز کنید:

ndk-build

Android.mk خود را برای فعال کردن تراز ELF 16 کیلوبایتی به روز کنید:

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

CMake

CMakeLists.txt خود را برای فعال کردن تراز ELF 16 کیلوبایتی به روز کنید:

target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384")

اندروید NDK r27 و بالاتر

برای پشتیبانی از کامپایل کتابخانه های اشتراکی تراز شده با ۱۶ کیلوبایت با Android NDK نسخه r27 و بالاتر، باید پرچم های ndk-build ، build.gradle ، build.gradle.kts یا پیوند دهنده خود را به صورت زیر به روز کنید:

ndk-build

در Application.mk شما:

APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true

شیار

در فایل 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"
      }
    }
  }
}

کاتلین

در فایل 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 کیلوبایت تراز باشد، اگر مکان‌هایی در کد شما فرض کنند که دستگاه از اندازه صفحه خاصی استفاده می‌کند، برنامه شما می‌تواند با خطا مواجه شود. برای جلوگیری از این، مراحل زیر را انجام دهید:

  1. هر گونه وابستگی کدگذاری سختی که به ثابت PAGE_SIZE اشاره می کند یا نمونه هایی در منطق کد شما که اندازه صفحه دستگاه را 4 کیلوبایت فرض می کند ( 4096 ) را حذف کنید.

    به جای آن از getpagesize() یا sysconf(_SC_PAGESIZE) استفاده کنید.

  2. به دنبال موارد استفاده از mmap() و سایر API هایی باشید که به آرگومان های صفحه تراز شده نیاز دارند و در صورت لزوم با جایگزین ها جایگزین کنید.

در برخی موارد، اگر برنامه شما از PAGE_SIZE به‌عنوان یک مقدار مناسب استفاده می‌کند که به اندازه صفحه اصلی مرتبط نیست، این امر باعث نمی‌شود که برنامه شما هنگام استفاده در حالت 16 کیلوبایتی خراب شود. با این حال، اگر این مقدار با mmap بدون MAP_FIXED به هسته ارسال شود، هسته همچنان از یک صفحه کامل استفاده می‌کند که مقداری از حافظه را هدر می‌دهد. به این دلایل، وقتی حالت 16 کیلوبایتی در NDK r27 و بالاتر فعال باشد، PAGE_SIZE تعریف نشده است.

اگر برنامه شما از PAGE_SIZE به این روش استفاده می‌کند و هرگز مستقیماً این مقدار را به هسته منتقل نمی‌کند، به جای استفاده از PAGE_SIZE ، یک متغیر جدید با نام جدید ایجاد کنید تا نشان دهد که برای مقاصد دیگر استفاده می‌شود و صفحه حافظه واقعی را منعکس نمی‌کند.

برنامه خود را در یک محیط 16 کیلوبایتی تست کنید

بعد از اینکه برنامه خود را با پشتیبانی از دستگاه های 16 کیلوبایتی ساختید، می خواهید برنامه خود را در یک محیط 16 کیلوبایتی آزمایش کنید تا ببینید آیا برنامه شما دچار رگرسیون می شود یا خیر. برای انجام این کار؛ این موارد را دنبال کنید:

  1. Android 15 SDK را تنظیم کنید .

  2. یکی از محیط های تست زیر را تنظیم کنید:

  3. دستگاه تست خود را راه اندازی کنید، سپس دستور زیر را اجرا کنید تا مطمئن شوید که از یک محیط 16 کیلوبایتی استفاده می کند:

    adb shell getconf PAGE_SIZE
    

    دستور باید مقدار 16384 را برگرداند.

  4. برای هر کتابخانه مشترک، بررسی کنید که بخش‌های ELF کتابخانه‌های مشترک با استفاده از تراز ELF 16 کیلوبایتی به درستی تراز شده باشند. برای کمک به این فرآیند می توانید از این اسکریپت استفاده کنید:

    #!/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
    
    1. اسکریپت را در فایلی مانند alignment.sh ذخیره کنید.

    2. فایل APK برنامه خود را استخراج کنید:

      unzip APK_NAME.apk -d /tmp/my_apk_out
      
    3. اسکریپت را روی فایل های استخراج شده در پوشه /tmp/my_apk_out اجرا کنید:

      alignment.sh /tmp/my_apk_out | grep "arm64-v8a"
      

      خروجی اسکریپت ALIGNED یا UNALIGNED برای همه کتابخانه های مشترک arm64-v8a .

    4. اگر هر یک از کتابخانه‌های مشترک arm64-v8a UNALIGNED هستند، باید بسته‌بندی آن کتابخانه‌ها را به‌روزرسانی کنید ، سپس برنامه خود را مجدداً کامپایل کرده و با دنبال کردن مراحل این بخش مجدداً آزمایش کنید.

  5. دستور zipalign زیر را اجرا کنید تا مطمئن شوید برنامه شما 16 کیلوبایت تراز شده است، جایی که APK_NAME نام فایل APK برنامه شما است:

    zipalign -c -P 16 -v 4 APK_NAME.apk
    
  6. برنامه خود را به طور کامل آزمایش کنید و بر روی مناطقی تمرکز کنید که ممکن است با تغییر نمونه کدهایی که به اندازه های صفحه خاصی اشاره می کنند تحت تأثیر قرار گیرند.

شبیه ساز Android را با یک تصویر سیستم Android 15 مبتنی بر 16 کیلوبایت تنظیم کنید

برای راه اندازی یک محیط 16 کیلوبایتی با استفاده از شبیه ساز اندروید، مراحل زیر را دنبال کنید:

  1. تصاویر سیستم شبیه ساز اندروید 15 مبتنی بر 16 کیلوبایت با اندروید استودیو Jellyfish سازگار است | 2023.3.1 یا بالاتر. با این حال، برای بهترین تجربه هنگام کار با اندروید 15 بتا، آخرین نسخه پیش نمایش اندروید استودیو را دانلود کنید.

    به یاد داشته باشید که می‌توانید نسخه موجود Android Studio خود را نصب کنید، زیرا می‌توانید چندین نسخه را در کنار هم نصب کنید .

  2. در Android Studio، روی Tools > SDK Manager کلیک کنید.

  3. در برگه پلتفرم‌های SDK ، Show Package Details را علامت بزنید، سپس بخش Android VanillaIceCream Preview را باز کنید و بسته به دستگاه‌های مجازی که می‌خواهید ایجاد کنید، یکی یا هر دو تصویر سیستم شبیه‌ساز زیر را انتخاب کنید:

    • Google APIs Experimental 16k Size Page Size ARM 64 v8a System Image
    • Google APIs Experimental 16k Page Size Intel x86_64 Atom System Image

    با استفاده از SDK Manager در اندروید استودیو، تصاویر سیستم شبیه ساز 16 کیلوبایتی را دانلود کنید

  4. روی Apply > OK کلیک کنید تا هر کدام از تصاویر سیستمی را که انتخاب کرده اید دانلود کنید.

  5. مراحل راه اندازی یک دستگاه مجازی برای Android 15 را دنبال کنید و هنگامی که از شما خواسته شد یک تصویر سیستم را انتخاب کنید، تصویر سیستمی 16 کیلوبایتی را که دانلود کرده اید انتخاب کنید. اگر به طور خودکار توصیه نمی شود، می توانید تصویر سیستم 16 کیلوبایتی را در برگه سایر تصاویر پیدا کنید.

    تصویر شبیه ساز 16 کیلوبایتی را در تب Other Images پیدا کنید