Urządzenia wielordzeniowe i Xamarin.Android
System Android może działać w kilku różnych architekturach komputerów. W tym dokumencie omówiono różne architektury procesora CPU, które mogą być stosowane dla aplikacji platformy Xamarin.Android. W tym dokumencie wyjaśniono również, w jaki sposób aplikacje systemu Android są pakowane w celu obsługi różnych architektur procesora CPU. Zostanie wprowadzony interfejs binarny aplikacji (ABI), a wskazówki zostaną podane w odniesieniu do interfejsów API używanych w aplikacji platformy Xamarin.Android.
Omówienie
System Android umożliwia tworzenie "plików binarnych tłuszczu", jednego .apk
pliku zawierającego kod maszyny, który będzie obsługiwać wiele, różnych architektur procesora CPU. Jest to realizowane przez skojarzenie każdego fragmentu kodu maszynowego z interfejsem binarnym aplikacji. Usługa ABI służy do kontrolowania, który kod maszyny będzie uruchamiany na danym urządzeniu sprzętowym. Na przykład aby aplikacja systemu Android była uruchamiana na urządzeniu x86, podczas kompilowania aplikacji należy uwzględnić obsługę architektury X86 ABI.
W szczególności każda aplikacja systemu Android będzie obsługiwać co najmniej jeden osadzony interfejs binarny aplikacji (EABI). EABI to konwencje specyficzne dla programów oprogramowania osadzonego. Typowe elementy, takie jak EABI, opisują następujące elementy:
Zestaw instrukcji procesora CPU.
Endianness pamięci przechowuje i ładuje się w czasie wykonywania.
Format binarny plików obiektów i bibliotek programów, a także tego, który typ zawartości jest dozwolony lub obsługiwany w tych plikach i bibliotekach.
Różne konwencje używane do przekazywania danych między kodem aplikacji a systemem (na przykład sposób rejestrowania i/lub stosu są używane, gdy są wywoływane funkcje, ograniczenia wyrównania itp.)
Ograniczenia wyrównania i rozmiaru dla typów wyliczenia, struktur, pól i tablic.
Lista symboli funkcji dostępnych dla kodu maszyny w czasie wykonywania, zazwyczaj z bardzo określonego zestawu bibliotek.
armeabi i bezpieczeństwo wątków
Interfejs binarny aplikacji zostanie szczegółowo omówiony poniżej, ale należy pamiętać, że armeabi
środowisko uruchomieniowe używane przez platformę Xamarin.Android nie jest bezpieczne wątkiem. Jeśli na urządzeniu wdrożono aplikację z armeabi
obsługą armeabi-v7a
, wystąpi wiele dziwnych i niewytłumaczalnych wyjątków.
Ze względu na usterkę w systemie Android 4.0.0, 4.0.1, 4.0.2 i 4.0.3 biblioteki natywne zostaną pobrane z armeabi
katalogu, mimo że istnieje armeabi-v7a
katalog, a urządzenie jest armeabi-v7a
urządzeniem.
Uwaga
Platforma Xamarin.Android zapewni, że .so
zostaną dodane do pliku APK w odpowiedniej kolejności. Ta usterka nie powinna być problemem dla użytkowników platformy Xamarin.Android.
Opisy ABI
Każda usługa ABI obsługiwana przez system Android jest identyfikowana przez unikatową nazwę.
armeabi
Jest to nazwa eaBI dla procesorów opartych na architekturze ARM, które obsługują co najmniej zestaw instrukcji ARMv5TE. Android podąża za little-endian ARM GNU/Linux ABI. Ta usługa ABI nie obsługuje obliczeń zmiennoprzecinkowych wspomaganych sprzętowo. Wszystkie operacje FP są wykonywane przez funkcje pomocnika oprogramowania pochodzące z biblioteki statycznej kompilatora libgcc.a
. Urządzenia SMP nie są obsługiwane przez armeabi
program .
Ważne
Kod platformy armeabi
Xamarin.Android nie jest bezpieczny wątkowo i nie powinien być używany na urządzeniach z wieloma procesorami CPU armeabi-v7a
(opisanych poniżej). Korzystanie z armeabi
kodu na urządzeniu z jednym rdzeniem armeabi-v7a
jest bezpieczne.
armeabi-v7a
Jest to kolejny zestaw instrukcji opartych na usłudze ARM, który rozszerza opisany powyżej zestaw instrukcji armeabi
EABI. Usługa armeabi-v7a
EABI obsługuje sprzętowe operacje zmiennoprzecinkowe i wiele urządzeń z procesorem CPU (SMP). Aplikacja korzystająca z interfejsu armeabi-v7a
EABI może oczekiwać znacznej poprawy wydajności w aplikacji korzystającej z programu armeabi
.
Uwaga
armeabi-v7a
kod maszyny nie zostanie uruchomiony na urządzeniach ARMv5.
arm64-v8a
Jest to zestaw instrukcji 64-bitowych oparty na architekturze procesora ARMv8. Ta architektura jest używana w Nexus 9. Platforma Xamarin.Android 5.1 wprowadziła obsługę tej architektury (aby uzyskać więcej informacji, zobacz obsługa 64-bitowego środowiska uruchomieniowego).
x86
Jest to nazwa ABI dla procesorów, które obsługują zestaw instrukcji powszechnie o nazwie x86 lub IA-32. Ten zestaw instrukcji ABI odpowiada instrukcjom zestawu instrukcji Pentium Pro, w tym zestawów instrukcji MMX, SSE2 i SSE3. Nie zawiera żadnych innych opcjonalnych rozszerzeń zestawu instrukcji IA-32, takich jak:
- instrukcja MOVBE.
- Dodatkowe rozszerzenie SSE3 (SSSE3).
- dowolny wariant SSE4.
Uwaga
Google TV, chociaż działa na x86, nie jest obsługiwany przez android NDK.
x86_64
Jest to nazwa ABI dla procesorów CPU obsługujących 64-bitowy zestaw instrukcji x86 (nazywany również x64 lub AMD64). Platforma Xamarin.Android 5.1 wprowadziła obsługę tej architektury (aby uzyskać więcej informacji, zobacz obsługa 64-bitowego środowiska uruchomieniowego).
Format pliku APK
Pakiet aplikacji systemu Android to format pliku, który zawiera cały kod, zasoby, zasoby i certyfikaty niezbędne dla aplikacji systemu Android. Jest .zip
to plik, ale używa .apk
rozszerzenia nazwy pliku. Po rozwinięciu zawartość utworzonego .apk
przez platformę Xamarin.Android jest widoczna na poniższym zrzucie ekranu:
Krótki opis zawartości .apk
pliku:
AndroidManifest.xml — jest
AndroidManifest.xml
to plik w formacie binarnym XML.classes.dex — zawiera kod aplikacji skompilowany w
dex
formacie pliku używanym przez maszynę wirtualną środowiska uruchomieniowego systemu Android.resources.arsc — ten plik zawiera wszystkie wstępnie skompilowane zasoby dla aplikacji.
lib — ten katalog przechowuje skompilowany kod dla każdej usługi ABI. Będzie zawierać jeden podfolder dla każdego ABI, który został opisany w poprzedniej sekcji. Na powyższym
.apk
zrzucie ekranu, pytanie zawiera biblioteki natywne zarówno dla , jakarmeabi-v7a
i dlax86
.META-INF — ten katalog (jeśli istnieje) jest używany do przechowywania informacji o podpisywaniu, pakietu i danych konfiguracji rozszerzenia.
res — ten katalog zawiera zasoby, które nie zostały skompilowane w pliku
resources.arsc
.
Uwaga
Plik libmonodroid.so
jest biblioteką natywną wymaganą przez wszystkie aplikacje platformy Xamarin.Android.
Obsługa ABI urządzenia z systemem Android
Każde urządzenie z systemem Android obsługuje wykonywanie kodu natywnego w maksymalnie dwóch interfejsach ABI:
"primary" ABI — odpowiada to kodowi maszyny używanemu w obrazie systemowym.
ABI "secondary" — jest to opcjonalny interfejs ABI , który jest również obsługiwany przez obraz systemu.
Na przykład typowe urządzenie ARMv5TE będzie miało tylko podstawową wartość ABI armeabi
klasy , podczas gdy urządzenie ARMv7 określa podstawową wartość ABI i pomocnicze ABI armeabi-v7a
armeabi
klasy . Typowe urządzenie x86 określałoby tylko podstawową wartość ABI .x86
Instalacja biblioteki natywnej systemu Android
W czasie instalacji pakietu biblioteki natywne w obiekcie .apk
są wyodrębniane do natywnego katalogu biblioteki aplikacji, zazwyczaj /data/data/<package-name>/lib
, i są następnie określane jako $APP/lib
.
Zachowanie instalacji biblioteki natywnej systemu Android różni się znacznie między wersjami systemu Android.
Instalowanie bibliotek natywnych: w wersji wcześniejszej niż Android 4.0
System Android wcześniejszych niż 4.0 Ice Cream Sandwich wyodrębni tylko biblioteki natywne z pojedynczego ABI w obrębie ..apk
Aplikacje systemu Android tego rocznika najpierw spróbują wyodrębnić wszystkie biblioteki natywne dla podstawowej usługi ABI, a jeśli takie biblioteki nie istnieją, system Android wyodrębni wszystkie biblioteki natywne dla pomocniczej usługi ABI. Nie jest wykonywane "scalanie".
Rozważmy na przykład sytuację, w której aplikacja jest zainstalowana na urządzeniu armeabi-v7a
. Element .apk,
, który obsługuje zarówno pliki, jak armeabi
i armeabi-v7a
, ma w nim następujące katalogi i pliki ABI lib
:
lib/armeabi/libone.so
lib/armeabi/libtwo.so
lib/armeabi-v7a/libtwo.so
Po zakończeniu instalacji katalog biblioteki natywnej będzie zawierał następujące elementy:
$APP/lib/libtwo.so # from the armeabi-v7a directory in the apk
Innymi słowy, nie libone.so
jest zainstalowany. Spowoduje to problemy, ponieważ libone.so
nie jest obecne, aby aplikacja ładowała się w czasie wykonywania. To zachowanie, choć nieoczekiwane, zostało zarejestrowane jako usterka i ponownie sklasyfikowane jako "działające zgodnie z oczekiwaniami".
W związku z tym w przypadku określania wersji systemu Android wcześniejszych niż 4.0 należy podać wszystkie biblioteki natywne dla każdego usługi ABI, które będzie obsługiwać aplikacja, .apk
czyli powinna zawierać:
lib/armeabi/libone.so
lib/armeabi/libtwo.so
lib/armeabi-v7a/libone.so
lib/armeabi-v7a/libtwo.so
Instalowanie bibliotek natywnych: Android 4.0 — Android 4.0.3
Android 4.0 Ice Cream Sandwich zmienia logikę wyodrębniania. Spowoduje to wyliczenie wszystkich bibliotek natywnych, sprawdzenie, czy nazwa bazowa pliku została już wyodrębniona, a oba następujące warunki zostaną spełnione, a biblioteka zostanie wyodrębniona:
Nie został jeszcze wyodrębniony.
Biblioteka natywna ABI jest zgodna z podstawowym lub pomocniczym ABI obiektu docelowego.
Spełnienie tych warunków umożliwia zachowanie "scalania"; oznacza to, że jeśli mamy element .apk
z następującą zawartością:
lib/armeabi/libone.so
lib/armeabi/libtwo.so
lib/armeabi-v7a/libtwo.so
Następnie po zakończeniu instalacji katalog biblioteki natywnej będzie zawierał następujące elementy:
$APP/lib/libone.so
$APP/lib/libtwo.so
Niestety, to zachowanie jest zależne od kolejności, zgodnie z opisem w następującym dokumencie - Problem 24321: Galaxy Nexus 4.0.2 używa armeabi kodu natywnego, gdy zarówno armeabi, jak i armeabi-v7a są uwzględnione w pliku apk.
Biblioteki natywne są przetwarzane "w kolejności" (na przykład rozpakowywanie), a pierwsze dopasowanie jest wyodrębniane. Ponieważ zawiera .apk
armeabi
i armeabi-v7a
wersje libtwo.so
elementu , a armeabi
element jest wymieniony jako pierwszy, jest armeabi
to wersja wyodrębniona, a nie armeabi-v7a
wersja:
$APP/lib/libone.so # armeabi
$APP/lib/libtwo.so # armeabi, NOT armeabi-v7a!
Ponadto, nawet jeśli określono oba armeabi
elementy i armeabi-v7a
ABI (zgodnie z opisem poniżej w sekcji Deklarowanie obsługiwanych interfejsów ABI), platforma Xamarin.Android utworzy następujący element w pliku .
csproj
:
<AndroidSupportedAbis>armeabi,armeabi-v7a</AndroidSupportedAbis>
armeabi
libmonodroid.so
W związku z tym element zostanie znaleziony jako pierwszy w obiekcie .apk
i armeabi
libmonodroid.so
będzie to element wyodrębniony, mimo że armeabi-v7a
libmonodroid.so
element jest obecny i zoptymalizowany pod kątem celu. Może to również spowodować niejasne błędy czasu wykonywania, ponieważ armeabi
nie jest bezpieczne SMP.
Instalowanie bibliotek natywnych: Android 4.0.4 lub nowszy
System Android 4.0.4 zmienia logikę wyodrębniania: wylicza wszystkie biblioteki natywne, odczytuje nazwę podstawową pliku, a następnie wyodrębnia podstawową wersję usługi ABI (jeśli istnieje) lub pomocniczą usługę ABI (jeśli istnieje). Umożliwia to zachowanie "scalania"; oznacza to, że jeśli mamy element .apk
z następującą zawartością:
lib/armeabi/libone.so
lib/armeabi/libtwo.so
lib/armeabi-v7a/libtwo.so
Następnie po zakończeniu instalacji katalog biblioteki natywnej będzie zawierał następujące elementy:
$APP/lib/libone.so # from armeabi
$APP/lib/libtwo.so # from armeabi-v7a
Zestawy Xamarin.Android i ABI
Platforma Xamarin.Android obsługuje następujące architektury 64-bitowe :
arm64-v8a
x86_64
Uwaga
Od sierpnia 2018 r. nowe aplikacje będą wymagane do określania docelowego poziomu interfejsu API na poziomie 26, a od sierpnia 2019 r. aplikacje będą musiały zapewnić 64-bitowe wersje oprócz wersji 32-bitowej.
Platforma Xamarin.Android obsługuje następujące architektury 32-bitowe:
armeabi
^armeabi-v7a
x86
Uwaga
^Od wersji Xamarin.Android 9.2armeabi
nie jest już obsługiwana.
Platforma Xamarin.Android obecnie nie zapewnia obsługi programu mips
.
Deklarowanie obsługiwanych ABI
Domyślnie platforma Xamarin.Android będzie domyślnie dla armeabi-v7a
kompilacji wydania i kompilacji debugowania oraz x86
dla armeabi-v7a
kompilacji debugowania. Obsługę różnych interfejsów API można ustawić za pomocą opcji projektu dla projektu Xamarin.Android. W programie Visual Studio można to ustawić na stronie Opcje systemu Android właściwości projektu na karcie Zaawansowane, jak pokazano na poniższym zrzucie ekranu:
W Visual Studio dla komputerów Mac obsługiwane architektury można wybrać na stronie Kompilacja systemu Android opcji projektu na karcie Zaawansowane, jak pokazano na poniższym zrzucie ekranu:
Istnieją pewne sytuacje, w których może być konieczne zadeklarowanie dodatkowej pomocy technicznej usługi ABI, na przykład w następujących sytuacjach:
Wdrażanie aplikacji na urządzeniu
x86
.Wdrażanie aplikacji na urządzeniu
armeabi-v7a
w celu zapewnienia bezpieczeństwa wątków.
Podsumowanie
W tym dokumencie omówiono różne architektury procesora CPU, na których może działać aplikacja systemu Android. Wprowadzono interfejs binarny aplikacji i sposób jego użycia przez system Android do obsługi różnych architektur procesora CPU.
Następnie omówiliśmy sposób określania obsługi ABI w aplikacji platformy Xamarin.Android i wyróżniono problemy występujące podczas korzystania z aplikacji platformy Xamarin.Android na armeabi-v7a
urządzeniu przeznaczonym tylko dla programu armeabi
.