添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
活泼的小熊猫  ·  Breautek | Preparing ...·  6 天前    · 
发呆的面包  ·  Python in Excel will ...·  3 周前    · 
刚失恋的烤面包  ·  Mac ...·  11 月前    · 
失恋的茶壶  ·  python 3 typeerror ...·  1 年前    · 

Knowledge Prerequisites

  • Experience with the Android Studio IDE or the SDK Manager command line.
  • CMake or other build tools for compiling native modules
  • What are page sizes?

    Page Sizes is a way that operating systems allocate memory for applications.

    If an application requests 1 byte to be allocated, the application will allocate 1 byte of memory from a page that is assigned to the application, if available. If there is no memory available to be allocated from a page, a new page will be created.

    Historically, all android devices were configured to use 4KB page sizes. So when the android OS needs to create a new page of memory for an application, it will allocate 4kb of RAM for the application.

    Starting with Android 15 , devices may be configured to use 16kb page sizes instead. This means these devices will be allocating larger pages, so that it can reduce the amount of pages the device needs to manage or create.

    Devices configured with 16KB page sizes will not load up native binaries that was compiled with 4kb page size memory.

    How does this affect me as an Android Developer?

    Well if you're android projects contain purely Java and/or Kotlin code, then you don't need to do anything within your own code base. You might have to check if any dependencies you import contains native modules, and if so, they will need be updated with a version that supports 16kb page memory.

    Attempting to load a 4kb page size module into a 16kb page size device will yield runtime errors such as the one below:

    java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH/DT_GNU_HASH in "/data/app/~~8yW8cmL4SiL7B4WQLUoSOA==/com.example.package.testapp-yOfVv6oKzfxtGAE_SZwGqQ==/base.apk!/lib/x86_64/libmylib.so" (new hash type from the future?)
    

    These binaries that produce this error needs to be recompiled with 16kb page support.

    Enabling 16KB page support

    Enabling 16kb page support is as adding the CMake's ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES flag. NDK 27 will be required for this flag.

    namespace = "..." compileSdk = 34 ndkVersion = "27.0.12077973" defaultConfig { externalNativeBuild { cmake { version = "3.22.1" arguments += listOf("-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON") cppFlags += ""

    If you do not use the libc++ library, or cannot upgrade to NDK 27, or don't use CMake. Then you can enable 16kb page size binaries by using the compiler flag: -Wl,-z,max-page-size=16384.

    If you DO use the libc++ library (aka libc++_shared.so), then NDK 27 is required. Older NDK versions will not have a 16kb compatible libc++ library.

    In my testing, building for 16kb page size support is backwards compatible to 4kb page size devices.

    Optimising for 16kb page sizes

    Because your native modules is not known where they will be ran ahead of time, and even though Android 15 supports a 16kb page size configuration, it doesn't mean they will be 16kb page size configured.

    Therefore, it's recommended to check for the page size at runtime instead of relying on compiler flags. Android can use the getpagesize method to do this.

    It will be inefficient to allocate a 4kb buffer when the OS might allocate you an entire 16kb page for that buffer. It's far more efficient to allocate a page worth of memory, or in multiples of a page for your buffers.

    #include <unistd.h>
    #include <stdio.h>
    const int PAGE_SIZE = getpagesize();
    const unsigned long bufferSize = PAGE_SIZE * 1; // Number of pages we wanted to allocate
    char buffer[bufferSize]; //4096 or 16384 buffer
    

    Testing on 16kb virtual machines

    Lastly even if you don't have a physical device, there are 16kb simulators available.

    You'll need at least Android Studio Koala 2024.1.2 or later (Currently Beta 1, at the time of writing) and the following packages:

  • Android SDK Platform VanillaIceCream rev 4 or later
  • Google APIs Experimental 16k Page Size (Intel x86_64 if on Intel/AMD CPU, or arm64 if on M-based macOS)
  • Android SDK Build-Tools 35
  • NDK 27.0.12077973 (Do not use the RC versions, they were broken for me)
  • Android SDK Command-line Tools 13.0 or later
  • CMake 3.22.1 or later
  • Android Emulator 34.2.16 or later
  • Android SDK Platform-Tools or later
  • Note: Android Studio Koala 2024.1.1 will work for building and running, but the debugger will not attach.

    Note: there is an API 35 16k emulator, which currently fails to boot for me. The arm64 version however does work on my M-based MacOS. The VanillaIceCream version works in both environments.

    With the above configuration, you should be able to create a 16kb page simulator and test to see if your native binaries will load properly to prepare for the next generation of Android devices.

    Norman Breau is an IT professional with over 10 years of field experience. He has a wide range of skill sets, ranging from web & software development & architecture, to Server & Database administration. Presently he works at TotalPave where he plays a lead role in software projects as well as manages the server infrastructure. On his own time, he volunteers to some open source projects, namely Apache Cordova, as many projects throughout his career were dependent on the Cordova project. Open source projects works the best when there are volunteers that depend on such software is able to contribute in some form. Additionally, he has been working on a newer project called Fuse, a framework for building native-web hybrid mobile applications. The framework intends to fill a void somewheres between CapacitorJS and pure native development. Fuse is simply just a native library, with a bundleable webview JS API. Unlike Cordova and CapacitorJS, Fuse is more tailored to native developers, who want to still utilise the webview for their application's UI but retain full control over the native project and native code. The only requirement is that Fuse needs to be installed in the application along with a compatible Fuse JS runtime. Fuse offers the webview and a bridging API that natively supports binary and is incredibly fast. Like all websites, web hosting costs money. If the above article has helped you, please considering offering a small tip as a token of appreciation.