Zařízení s více jádry a Xamarin.Android

Android může běžet v několika různých počítačových architekturách. Tento dokument popisuje různé architektury procesoru, které mohou být použity pro aplikaci Xamarin.Android. Tento dokument také vysvětluje, jak jsou aplikace pro Android zabalené tak, aby podporovaly různé architektury procesoru. Zavádí se binární rozhraní aplikace (ABI) a pokyny budou poskytnuty ohledně toho, které ABI se mají použít v aplikaci Xamarin.Android.

Přehled

Android umožňuje vytvořit "fat binaries", jeden .apk soubor, který obsahuje strojový kód, který bude podporovat více různých architektur procesoru. Toho se dosahuje přidružením každé části strojového kódu k binárnímu rozhraní aplikace. ABI slouží k řízení, který kód počítače se bude spouštět na daném hardwarovém zařízení. Například aby aplikace pro Android běžela na zařízení x86, je nutné při kompilaci aplikace zahrnout podporu X86 ABI.

Konkrétně každá aplikace pro Android bude podporovat alespoň jedno binární rozhraní vložené aplikace (EABI). EABI jsou konvence specifické pro vložené softwarové programy. Typický EABI popisuje například:

  • Sada instrukcí procesoru.

  • Endianness úložišť a načítání paměti za běhu.

  • Binární formát souborů objektů a knihoven programů, stejně jako typ obsahu je povolen nebo podporován v těchto souborech a knihovnách.

  • Různé konvence používané k předávání dat mezi kódem aplikace a systémem (například jak se registrují a/nebo zásobník používají, když se volají funkce, omezení zarovnání atd.)

  • Omezení zarovnání a velikosti pro typy výčtů, struktury, pole a pole

  • Seznam symbolů funkcí dostupných pro váš strojový kód za běhu, obecně z velmi konkrétní vybrané sady knihoven.

armeabi a thread Sejf ty

Binární rozhraní aplikace bude podrobně popsáno níže, ale je důležité si uvědomit, že armeabi modul runtime používaný Xamarin.Android není bezpečný podproces. Pokud je na zařízení nasazená aplikace s armeabi podporou, dojde k armeabi-v7a mnoha podivným a nevysvětlitelným výjimkám.

Kvůli chybě v Androidu 4.0.0, 4.0.1, 4.0.2 a 4.0.3 se nativní knihovny vyzvednou z armeabi adresáře, i když existuje armeabi-v7a adresář a zařízení je armeabi-v7a zařízení.

Poznámka:

Xamarin.Android zajistí, že .so jsou přidány do APK ve správném pořadí. Tato chyba by neměla být problémem pro uživatele Xamarin.Android.

Popisy ABI

Každý ABI podporovaný Androidem je identifikován jedinečným názvem.

armeabi

Toto je název EABI pro procesory založené na ARM, které podporují alespoň instrukční sadu ARMv5TE. Android se řídí little-endian ARM GNU/Linux ABI. Tato funkce ABI nepodporuje výpočty s plovoucí desetinou čárkou s podporou hardwaru. Všechny operace FP provádí pomocné funkce softwaru, které pocházejí ze statické knihovny kompilátoru libgcc.a . Zařízení SMP nejsou podporována armeabinástrojem .

Důležité

Kód Xamarin.Androidu armeabi není bezpečný z více vláken a neměl by se používat na zařízeních s více procesory armeabi-v7a (popsané níže). Použití armeabi kódu na jednojádrový armeabi-v7a zařízení je bezpečné.

armeabi-v7a

Toto je další sada instrukcí procesoru založená na ARM, která rozšiřuje armeabi EABI popsané výše. EABI armeabi-v7a podporuje hardwarové operace s plovoucí desetinou čárkou a několik zařízení s procesorem (SMP). Aplikace, která používá armeabi-v7a EABI, může očekávat výrazné zvýšení výkonu u aplikace, která používá armeabi.

Poznámka:

armeabi-v7a na zařízeních ARMv5 se nespustí kód počítače.

arm64-v8a

Jedná se o 64bitovou instrukční sadu založenou na architektuře procesoru ARMv8. Tato architektura se používá v zařízení Nexus 9. Xamarin.Android 5.1 zavedl podporu pro tuto architekturu (další informace najdete v 64bitové podpoře modulu runtime).

x86

Toto je název ABI pro procesory, které podporují instrukční sadu běžně pojmenovanou x86 nebo IA-32. Tento ABI odpovídá pokynům pro instrukční sadu Pentium Pro, včetně množin MMX, SSE, SSE2 a SSE3. Neobsahuje žádná další volitelná rozšíření instrukční sady IA-32, například:

  • instrukce MOVBE.
  • Doplňkové rozšíření SSE3 (SSSE3).
  • libovolnou variantu SSE4.

Poznámka:

Google TV, i když běží na platformě x86, není podporován NDK Androidu.

x86_64

Toto je název ABI pro procesory, které podporují 64bitovou instrukční sadu x86 (označovanou také jako x64 nebo AMD64). Xamarin.Android 5.1 zavedl podporu pro tuto architekturu (další informace najdete v 64bitové podpoře modulu runtime).

Formát souboru APK

Balíček aplikace pro Android je formát souboru, který obsahuje veškerý kód, prostředky, prostředky a certifikáty potřebné pro aplikaci pro Android. Jedná se o .zip soubor, ale používá příponu .apk názvu souboru. Po rozbalení se obsah vytvořeného .apk Xamarin.Androidem zobrazí na následujícím snímku obrazovky:

Contents of the .apk

Rychlý popis obsahu .apk souboru:

  • AndroidManifest.xml – jedná se o AndroidManifest.xml soubor v binárním formátu XML.

  • classes.dex – Obsahuje kód aplikace zkompilovaný do dex formátu souboru, který používá virtuální počítač s modulem Android Runtime.

  • resources.arsc – Tento soubor obsahuje všechny předkompilované prostředky pro aplikaci.

  • lib – Tento adresář obsahuje zkompilovaný kód pro každý ABI. Bude obsahovat jednu podsložku pro každou verzi ABI popsanou v předchozí části. Na výše uvedeném snímku obrazovky .apk obsahuje příslušné nativní knihovny pro obě armeabi-v7a i pro x86 .

  • META-INF – Tento adresář (pokud je k dispozici) slouží k ukládání podpisových informací, balíčků a konfiguračních dat rozšíření.

  • res – Tento adresář obsahuje prostředky, které nebyly zkompilovány do resources.arsc .

Poznámka:

Soubor libmonodroid.so je nativní knihovna vyžadovaná všemi aplikacemi Xamarin.Android.

Podpora ABI pro zařízení s Androidem

Každé zařízení s Androidem podporuje spouštění nativního kódu v až dvou rozhraních ABI:

  • "primární" ABI – Odpovídá strojový kód použitý v systémové imagi.

  • "Sekundární" ABI – Jedná se o volitelnou verzi ABI , kterou podporuje také systémová image.

Například typické zařízení ARMv5TE bude mít pouze primární ABI armeabi, zatímco ARMv7 zařízení by určilo primární ABI a sekundární ABI armeabi-v7aarmeabi. Typické zařízení x86 by zadalo pouze primární ABI x86.

Instalace nativní knihovny pro Android

V době instalace balíčku se nativní knihovny v rámci aplikace .apk extrahují do nativního adresáře knihovny, obvykle /data/data/<package-name>/liba následně se označují jako $APP/lib.

Chování instalace nativní knihovny androidu se výrazně liší mezi verzemi Androidu.

Instalace nativních knihoven: Před Androidem 4.0

Android před verzí 4.0 Ice Cream Sandwich extrahuje pouze nativní knihovny z jediného ABI v rámci .apk. Aplikace pro Android tohoto vintage se nejprve pokusí extrahovat všechny nativní knihovny pro primární ABI, a pokud žádné takové knihovny neexistují, Android pak extrahuje všechny nativní knihovny pro sekundární ABI. Není dokončeno žádné sloučení.

Představte si například situaci, kdy je aplikace nainstalovaná na armeabi-v7a zařízení. Ten .apk, podporuje oba armeabiarmeabi-v7aadresáře a soubory ABI lib v něm:

lib/armeabi/libone.so
lib/armeabi/libtwo.so
lib/armeabi-v7a/libtwo.so

Po instalaci bude adresář nativní knihovny obsahovat:

$APP/lib/libtwo.so # from the armeabi-v7a directory in the apk

Jinými slovy, není nainstalována žádná libone.so . To způsobí problémy, protože libone.so aplikace se nenačte za běhu. Toto chování, zatímco neočekávané, bylo zaznamenáno jako chyba a přetříděno jako "funguje podle očekávání".

Při cílení na verze Androidu starší než 4.0 je proto nutné poskytnout všem nativním knihovnám pro každý ABI, které bude aplikace podporovat, to znamená, .apk že by měla obsahovat:

lib/armeabi/libone.so
lib/armeabi/libtwo.so
lib/armeabi-v7a/libone.so
lib/armeabi-v7a/libtwo.so

Instalace nativních knihoven: Android 4.0 – Android 4.0.3

Android 4.0 Ice Cream Sandwich mění logiku extrakce. Zobrazí výčet všech nativních knihoven, zjistí, jestli už byl extrahovaný název souboru, a pokud jsou splněny obě následující podmínky, knihovna se extrahuje:

  • Ještě nebyl extrahován.

  • ABI nativní knihovny odpovídá primární nebo sekundární ABI cíle.

Splnění těchto podmínek umožňuje "slučování" chování; to znamená, že pokud máme .apk následující obsah:

lib/armeabi/libone.so
lib/armeabi/libtwo.so
lib/armeabi-v7a/libtwo.so

Po instalaci bude adresář nativní knihovny obsahovat:

$APP/lib/libone.so
$APP/lib/libtwo.so

Toto chování je bohužel závislé na pořadí, jak je popsáno v následujícím dokumentu - Problém 24321: Galaxy Nexus 4.0.2 používá armeabi nativní kód, když armeabi a armeabi-v7a je součástí apk.

Nativní knihovny se zpracovávají v uvedeném pořadí (například rozbalit) a první shoda se extrahuje. Vzhledem k tomu, .apk že obsahuje armeabi a armeabi-v7a verze libtwo.soa armeabi je uvedena jako první, je armeabi to verze, která se extrahuje, nikoli verze armeabi-v7a :

$APP/lib/libone.so # armeabi
$APP/lib/libtwo.so # armeabi, NOT armeabi-v7a!

Navíc, i když jsou zadány obě armeabi a armeabi-v7a ABI (jak je popsáno níže v části deklarování podporovaných ABI), Xamarin.Android vytvoří následující prvek v souboru . csproj:

<AndroidSupportedAbis>armeabi,armeabi-v7a</AndroidSupportedAbis>

V důsledku toho armeabilibmonodroid.so se nejprve najde v rámci .apkalibmonodroid.soarmeabibude to ten, který se extrahuje, i když armeabi-v7alibmonodroid.so je přítomný a optimalizovaný pro cíl. To může také vést k nejasným chybám za běhu, protože armeabi není bezpečný SMP.

Instalace nativních knihoven: Android 4.0.4 a novější

Android 4.0.4 změní logiku extrakce: vytvoří výčet všech nativních knihoven, přečte základní název souboru a pak extrahuje primární verzi ABI (pokud existuje) nebo sekundární ABI (pokud je k dispozici). To umožňuje "slučování" chování; to znamená, že pokud máme .apk následující obsah:

lib/armeabi/libone.so
lib/armeabi/libtwo.so
lib/armeabi-v7a/libtwo.so

Po instalaci bude adresář nativní knihovny obsahovat:

$APP/lib/libone.so # from armeabi
$APP/lib/libtwo.so # from armeabi-v7a

Xamarin.Android a ABI

Xamarin.Android podporuje následující 64bitové architektury:

  • arm64-v8a
  • x86_64

Poznámka:

Od srpna 2018 budou nové aplikace nutné pro cílovou úroveň rozhraní API 26 a od srpna 2019 budou aplikace nutné k poskytování 64bitových verzí kromě 32bitové verze.

Xamarin.Android podporuje tyto 32bitové architektury:

  • armeabi ^
  • armeabi-v7a
  • x86

Poznámka:

^Od verze Xamarin.Android 9.2armeabi se už nepodporuje.

Xamarin.Android v současné době neposkytuje podporu pro mips.

Deklarace podporovaných ABI

Ve výchozím nastavení bude Xamarin.Android ve výchozím armeabi-v7a nastavení používat buildy vydaných verzí a armeabi-v7a pro sestavení ladění a x86 pro sestavení ladění . Podporu různých abi je možné nastavit prostřednictvím možností projektu Xamarin.Android. V sadě Visual Studio to lze nastavit na stránce Možnosti androidu vlastností projektu na kartě Upřesnit, jak je znázorněno na následujícím snímku obrazovky:

Android Options Advanced properties

V Visual Studio pro Mac mohou být podporované architektury vybrány na stránce Možnosti sestavení androidu na kartě Upřesnit, jak je znázorněno na následujícím snímku obrazovky:

Android Build Supported ABIs

V některých situacích může být nutné deklarovat další podporu ABI, například když:

  • Nasazení aplikace do x86 zařízení

  • Nasazení aplikace do armeabi-v7a zařízení za účelem zajištění bezpečnosti vláken

Shrnutí

Tento dokument popisuje různé architektury procesoru, na kterých může aplikace pro Android běžet. Představila binární rozhraní aplikace a způsob, jakým ho Android používá k podpoře různorodých architektur procesoru. Pak pokračoval v diskuzi o tom, jak určit podporu ABI v aplikaci Xamarin.Android a zdůraznil problémy, ke kterým dochází při použití aplikací Xamarin.Android na armeabi-v7a zařízení, které jsou určeny pouze pro armeabi.