W przeszłości Android obsługiwał jedynie strony o rozmiarze 4 KB, które obsługują zoptymalizowana wydajność pamięci systemowej dla średniej ilości pamięci Urządzenia z Androidem zwykle mają Począwszy od Androida 15, AOSP obsługuje urządzenia skonfigurowane pod kątem używania strony o rozmiarze 16 KB (16 KB). urządzenia). Jeśli aplikacja korzysta z jakichkolwiek bibliotek NDK, bezpośrednio lub pośrednio za pomocą pakietu SDK, musisz ponownie skompilować aplikację, na urządzeniach o rozmiarze 16 KB.
W miarę jak producenci tworzą urządzenia, na których jest coraz więcej pamięci fizycznej (RAM) wiele z tych urządzeń będzie miało rozmiar 16 KB, w celu optymalizacji wydajności urządzenia. Dodaję obsługa urządzeń o rozmiarze strony 16 KB umożliwia urządzeń i pomaga aplikacji czerpać korzyści z powiązanej wydajności wiele ulepszeń. Bez ponownej kompilacji aplikacje mogą nie działać na urządzeniach o rozmiarze 16 KB podczas produkcji w kolejnych wersjach Androida.
Aby pomóc Ci w obsłudze aplikacji, przygotowaliśmy wskazówki, jak sprawdzić, jeśli ma to wpływ na Twoją aplikację, jak stworzyć aplikację ponownie (w stosownych przypadkach) i jak przetestować ją środowisko o wielkości 16 KB z emulatorami (w tym Android 15). obrazów systemu dla emulatora Androida).
Korzyści i wzrost wydajności
Urządzenia skonfigurowane z użyciem stron o rozmiarze 16 KB zużywają średnio nieco więcej pamięci, ale zyskują też różne ulepszenia wydajności zarówno systemu, jak i aplikacji:
- Krótszy czas uruchamiania aplikacji, gdy system jest pod presją pamięci: średnio o 3,16% krótszy, a w przypadku niektórych testowanych aplikacji o znacznie więcej (do 30%).
- Zmniejszone zużycie energii podczas uruchamiania aplikacji: średnio o 4,56%
- Szybsze uruchamianie aparatu: średnio o 4,48% szybsze uruchomienia z pamięci i o 6,60% szybsze uruchomienia „na zimno”
- Skrócony czas uruchamiania systemu: skrócenie o 8% (około 950 milisekund)
Te ulepszenia bazują na naszych wstępnych testach. Wyniki na rzeczywistych urządzeniach mogą się różnić. W miarę kontynuowania testów będziemy przeprowadzać dodatkową analizę potencjalnych zysków w przypadku aplikacji.
Sprawdź, czy zmiana wpłynie na Twoją aplikację
Jeśli aplikacja korzysta z kodu natywnego, musisz ponownie ją skompilować, aby obsługiwała urządzenia o pojemności 16 KB. Jeśli nie masz pewności, czy Twoja aplikacja używa kodu natywnego, użyj narzędzia APK Analyzer, aby sprawdzić, czy jest on obecny, a potem sprawdź wyrównanie segmentów ELF dla wszystkich znalezionych bibliotek współdzielonych.
Jeśli Twoja aplikacja używa tylko kodu napisanego w języku programowania Java lub Kotlin (w tym wszystkich bibliotekach i pakietach SDK), to jest już obsługiwana na urządzeniach o pojemności 16 KB. Zalecamy jednak przetestowanie aplikacji w środowisku 16 KB, aby sprawdzić, czy nie występują nieoczekiwane regresje w zachowaniu aplikacji.
Czy Twoja aplikacja korzysta z kodu natywnego?
Aplikacja używa kodu natywnego, jeśli spełnia co najmniej 1 z tych warunków:
- Aplikacja używa kodu C/C++ (natywnego). Jeśli aplikacja korzysta z NDK Androida, używa kodu natywnego.
- Twoja aplikacja zawiera linki do natywnych bibliotek lub zależności innych firm (np. pakietów SDK), które ich używają.
- Twoja aplikacja została utworzona przez zewnętrznego kreatora aplikacji, który używa na urządzeniu bibliotek natywnych.
Identyfikowanie bibliotek natywnych za pomocą narzędzia APK Analyzer
APK Analyzer to narzędzie, które pozwala oceniać różne aspekty utworzonego pliku APK. Aby sprawdzić, czy Twoja aplikacja korzysta z kodu natywnego czy z bibliotek, wykonaj te czynności:
- Otwórz Android Studio, a następnie kliknij Plik > Otwórz i wybierz dowolny projekt.
Na pasku menu kliknij Kompiluj > Przeanalizuj APK….
Wybierz plik APK, który chcesz przeanalizować.
Sprawdź folder
lib
, w którym przechowywane są pliki obiektów udostępnionych (.so
), jeśli takie istnieją. Jeśli występują jakiekolwiek pliki obiektów współdzielonych, aplikacja używa kodu natywnego. Jeśli nie ma plików obiektów współdzielonych lub folderulib
, aplikacja nie używa kodu natywnego.
Sprawdzanie wyrównania segmentów ELF w przypadku bibliotek współdzielonych
W przypadku wszystkich bibliotek udostępnionych sprawdź, czy ich segmenty ELF są prawidłowo wyrównane za pomocą wyrównania ELF 16 KB. Jeśli pracujesz na systemie Linux lub macOS, możesz użyć skryptu check_elf_alignment.sh
zgodnie z opisem w następnej sekcji. Możesz też używać narzędzi wiersza poleceń bezpośrednio.
Użyj skryptu check_elf_alignment.sh (Linux lub macOS)
Aby sprawdzić wyrównanie segmentów ELF za pomocą skryptu check_elf_alignment.sh
:
Zapisz skrypt
check_elf_alignment.sh
w pliku.Uruchom skrypt na pliku APK aplikacji:
check_elf_alignment.sh APK_NAME.apk
Skrypt zwraca wartość
ALIGNED
lubUNALIGNED
dla wszystkicharm64-v8a
zasobów wspólnych.Jeśli jakiekolwiek biblioteki współdzielone
arm64-v8a
lubx86_64
mają wartośćUNALIGNED
, musisz zaktualizować pakiety tych bibliotek, a następnie skompilować ponownie aplikację i ponownie ją przetestować, wykonując czynności opisane w tej sekcji.
Bezpośrednie korzystanie z narzędzi wiersza poleceń
Aby sprawdzić wyrównanie segmentów ELF bezpośrednio za pomocą narzędzi wiersza poleceń:
- Upewnij się, że pakiet Android SDK Build-Tools w wersji 35.0.0 lub nowszej oraz pakiet Android NDK są zainstalowane za pomocą Menedżera pakietu SDK w Android Studio lub narzędzia wiersza poleceń
sdkmanager
. Wyodrębnij plik APK aplikacji:
Linux lub macOS
unzip APK_NAME.apk -d /tmp/my_apk_out
Windows (PowerShell)
Expand-Archive -Path .\APK_NAME.apk -DestinationPath ~\tmp\my_apk_out
W katalogu tymczasowym, do którego wyodrębniono plik APK, sprawdź zawartość katalogu
lib
pod kątem plików obiektów udostępnionych (.so
). Są to te same pliki obiektów współdzielonych, które widzisz podczas identyfikowania bibliotek natywnych za pomocą narzędzia APK Analyzer. W przypadku każdego pliku obiektu współdzielonego uruchom to polecenie:Linux lub 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"
gdzie
SDK_ROOT_LOCATION
to ścieżka do katalogu, w którym zainstalowano pakiet SDK Androida,SHARED_OBJECT_FILE
to nazwa sprawdzanego pliku obiektu udostępnianego, aNDK_VERSION
to wersja zainstalowanego NDK Androida (np.28.0.12433566
). Wyjście w przypadku każdego sprawdzanego pliku będzie wyglądać mniej więcej tak: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
Sprawdź wiersze danych, aby się upewnić, że segmenty ładowania nie mają wartości niższych niż
2**14
. Jeśli dowolny segment wczytywania ma wartość2**13
,2**12
lub niższą, musisz zaktualizować pakowanie tych bibliotek, a następnie skompilować aplikację i ponownie ją przetestować, wykonując czynności opisane w tej sekcji.Następnie uruchom narzędzie wiersza poleceń
zipalign
na pliku APK aplikacji:Linux lub 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
Gdzie
SDK_ROOT_LOCATION
to ścieżka do katalogu, w którym zainstalowano pakiet SDK Androida, aAPK_NAME
to nazwa pliku APK aplikacji. Jeśli wszystkie współdzielone biblioteki są prawidłowo dopasowane, ostatni wiersz danych wyjściowych będzie zawierać komunikat „Verification successful” (Weryfikacja zakończona pomyślnie).Jeśli weryfikacja się nie powiedzie, niektóre biblioteki współdzielone trzeba będzie ponownie dostosować. W tym celu zaktualizuj pakowanie tych bibliotek, a następnie skompiluj ponownie aplikację i przeprowadź ponowny test, wykonując czynności opisane w tej sekcji.
Kompilowanie aplikacji z uwzględnieniem urządzeń z 16 KB
Aby obsługiwać urządzenia o rozmiary 16 KB, aplikacje korzystające z kodu natywnego powinny wykonać czynności opisane w następnych sekcjach. Jeśli zaktualizujesz AGP do wersji 8.5.1 lub nowszej i NDK do wersji r28 lub nowszej oraz używasz wstępnie skompilowanych zależności zgodnych z 16 KB, aplikacje będą domyślnie zgodne z 16 KB.
Zaktualizuj pakowanie swoich wspólnych bibliotek
Zalecamy przejście na AGP w wersji 8.5.1 lub nowszej i używanie niezdętych wspólnych bibliotek.
AGP w wersji 8.5.1 lub nowszej
Aplikacje na urządzeniach z 16 KB wymagają, aby biblioteki współużytkowane dostarczane w nieskompresowanej formie były dopasowane do granicy 16 KB. Aby to zrobić, musisz uaktualizować wtyczkę Android Gradle (AGP) do wersji 8.5.1 lub nowszej. Szczegółowe informacje o procesie uaktualnienia znajdziesz w sekcji Android Pomóż w uaktualnieniu wtyczki Gradle.
AGP w wersji 8.5 lub starszej.
Jeśli nie możesz uaktualnić AGP do wersji 8.5.1 lub nowszej, możesz zamiast tego użyć skompresowanych bibliotek wspólnych. Zaktualizuj konfigurację Gradle, aby Gradle kompresował biblioteki współdzielone podczas pakowania aplikacji. Pozwoli to uniknąć problemów z instalacją aplikacji z niezsynchronizowanymi bibliotekami współdzielonymi.
Groovy
W pliku build.gradle
dodaj tę opcję:
android {
...
packagingOptions {
jniLibs {
useLegacyPackaging true
}
}
}
Kotlin
W pliku build.gradle.kts
dodaj tę opcję:
android {
...
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
}
Kompilowanie aplikacji przy użyciu wyrównania ELF 16 KB
Aby aplikacja mogła działać na urządzeniach z 16 KB pamięci, segmenty ELF w bibliotekach wspólnych muszą być odpowiednio dopasowane za pomocą dopasowania ELF 16 KB.
Aby skompilować aplikację z wyrównaniem ELF 16 KB, wykonaj czynności opisane w jednej z poniższych sekcji, zależnie od wersji Android NDK, której używasz.
Android NDK r28 lub nowszy
NDK w wersji r28 i nowszych kompiluje domyślnie kod z wyrównaniem do 16 KB.
Android NDK r27
Aby umożliwić kompilowanie bibliotek współdzielonych dopasowanych do 16 KB za pomocą Android NDK w wersji r27 lub nowszej, musisz zaktualizować flagi ndk-build
, build.gradle
, build.gradle.kts
lub linkera w ten sposób:
ndk-build
Na stronie Application.mk
:
APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true
Groovy
W pliku build.gradle
ustaw argument -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
W pliku build.gradle.kts
ustaw argument -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")
}
}
}
}
Inne systemy kompilacji
Określ te flagi linkera:
-Wl,-z,max-page-size=16384
Android NDK r26 i starsze
Aby umożliwić kompilowanie współdzielonych bibliotek z wyrównaniem do 16 KB za pomocą Android NDK w wersji r26 lub niższej, musisz zaktualizować konfigurację ndk-build
lub cmake
w ten sposób:
ndk-build
Zaktualizuj Android.mk
, aby włączyć wyrównanie ELF 16 KB:
LOCAL_LDFLAGS += "-Wl,-z,max-page-size=16384"
CMake
Zaktualizuj CMakeLists.txt
, aby włączyć wyrównanie ELF 16 KB:
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384")
Sprawdź, czy istnieją fragmenty kodu, które odwołują się do określonych rozmiarów strony
Nawet jeśli aplikacja jest zgodna z rozmiarem 16 KB, może wyświetlać błędy, jeśli miejsca w kodzie zakładają, że urządzenie używa określonego rozmiaru strony. Aby tego uniknąć:
Usuń zakodowane na stałe zależności, które odwołują się do stałej
PAGE_SIZE
lub jej wystąpień w logice kodu, które zakładają, że rozmiar strony na urządzeniu to 4 KB (4096
).Zamiast tego użyj kolumny
getpagesize()
lubsysconf(_SC_PAGESIZE)
.Poszukaj wywołań funkcji
mmap()
i innych interfejsów API, które wymagają argumentów wyrównanych do strony, i w razie potrzeby zastąp je alternatywnymi funkcjami.
W niektórych przypadkach, jeśli Twoja aplikacja używa wartości PAGE_SIZE
, która nie jest powiązana z podstawowym rozmiarem strony, nie spowoduje to jej uszkodzenia podczas korzystania z trybu 16 KB. Jeśli jednak ta wartość zostanie przekazana do jądra z wartością mmap
bez MAP_FIXED
, jądro nadal będzie używać całej strony, co spowoduje marnowanie pamięci. Z tych powodów wartość PAGE_SIZE
jest niezdefiniowana, gdy tryb 16 KB jest włączony w NDK r27 lub nowszej wersji.
Jeśli Twoja aplikacja używa zmiennej PAGE_SIZE
w ten sposób i nigdy nie przekazuje tej wartości bezpośrednio do jądra, zamiast PAGE_SIZE
utwórz nową zmienną z nowym nazwą, aby odzwierciedlała ona inne przeznaczenie i nie odzwierciedlała rzeczywistej strony pamięci.
Sprawdzanie pakietów SDK pod kątem obsługi 16 KB
Wiele pakietów SDK jest zgodnych z rozmiarami stron 16 KB, zwłaszcza jeśli skompilujesz je samodzielnie lub użyjesz najnowszych wersji. Niektóre wstępnie utworzone pakiety SDK lub ich wersje nie są jednak zgodne z 16 KB, dlatego sprawdź na stronie każdego dostawcy pakietu SDK, której wersji użyć w przypadku 16 KB.
Testowanie aplikacji w środowisku o rozmiary 16 KB
Po skompilowaniu aplikacji z obsługą urządzeń o rozmiary 16 KB warto przetestować ją w takim środowisku, aby sprawdzić, czy nie występują w niej regresje. W tym celu należy wykonać następujące czynności:
Skonfiguruj jedno z tych środowisk testowych:
Uruchom urządzenie testowe, a potem uruchom to polecenie, aby sprawdzić, czy używa ono środowiska o rozmaju 16 KB:
adb shell getconf PAGE_SIZE
Polecenie powinno zwrócić wartość
16384
.Aby sprawdzić, czy aplikacja jest wyrównana co 16 KB, uruchom to polecenie
zipalign
, gdzie APK_NAME to nazwa pliku APK aplikacji:zipalign -c -P 16 -v 4 APK_NAME.apk
Dokładnie przetestuj aplikację, zwracając uwagę na obszary, na które może mieć wpływ zmian kodów odwołujących się do określonych rozmiarów stron.
Konfigurowanie emulatora Androida za pomocą obrazu systemu Android 15 opartym na 16 KB
Aby skonfigurować środowisko 16 KB za pomocą emulatora Androida, wykonaj te czynności:
Obrazy systemowe emulatora Androida 15 o rozmiary 16 KB są zgodne z Android Studio Jellyfish | 2023.3.1 lub nowszym. Aby jednak uzyskać najlepsze wrażenia podczas pracy z Androidem 15 w wersji beta, pobierz najnowszą wersję podglądową Android Studio.
Pamiętaj, że możesz zachować dotychczasową wersję Android Studio, ponieważ możesz zainstalować wiele wersji naraz.
W Android Studio kliknij Narzędzia > Menedżer pakietu SDK.
Na karcie Platformy pakietu SDK zaznacz pole Pokaż szczegóły pakietu, a potem rozwiń sekcję Android VanillaIceCream Preview i wybierz jeden lub oba te obrazy systemu emulatora, w zależności od tego, jakie urządzenia wirtualne chcesz utworzyć:
- Interfejsy API Google Eksperymentalny obraz systemowy ARM 64 v8a o rozmiarze strony 16 kB
- Interfejsy Google API – eksperymentalny obraz systemu Intel x86_64 Atom o rozmiarze strony 16 kB
Aby pobrać wybrane obrazy systemu, kliknij Zastosuj > OK.
Wykonaj czynności konfigurowania urządzenia wirtualnego dla Androida 15, a gdy pojawi się prośba o wybranie obrazu systemu, wybierz pobrany obraz systemu o rozmiary 16 KB. Jeśli nie jest zalecane automatyczne tworzenie, obraz systemu o rozmiary 16 KB znajdziesz na karcie Inne obrazy.
- W Menedżerze urządzeń kliknij 3 kropki obok obrazu o rozmiarze 16 KB, a następnie kliknij Pokaż na dysku.
- W tym folderze znajdź plik
config.ini
. Dodaj ten wiersz do pliku
config.ini
i zapisz zmiany:kernel.parameters = androidboot.page_shift=14
Aby sprawdzić zmiany, uruchom to polecenie, które powinno zwrócić wartość
16384
:adb shell getconf PAGE_SIZE
Włączanie trybu 16 KB na urządzeniu za pomocą opcji programisty
Od Androida 15 QPR1 możesz korzystać z opcji dla deweloperów, która jest dostępna na niektórych urządzeniach, aby uruchomić urządzenie w trybie 16 KB i przeprowadzić testy na urządzeniu.
Ta opcja dla deweloperów jest dostępna na tych urządzeniach:
- Pixel 8 i Pixel 8 Pro (z Androidem 15 QPR1 lub nowszym)
- Pixel 8a (z Androidem 15 QPR1 lub nowszym)