Udostępnij za pośrednictwem


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 armeabiprogram .

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:

Zawartość .apk

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 , jak armeabi-v7a i dla x86 .

  • 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 armeabiklasy , podczas gdy urządzenie ARMv7 określa podstawową wartość ABI i pomocnicze ABI armeabi-v7a armeabiklasy . 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.soelementu , 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 .apki 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łaściwości zaawansowane opcji systemu Android

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:

Obsługiwane interfejsy API kompilacji systemu Android

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.