Návod: Vytvoření vazby knihovny Android Kotlin
Důležité
V současné době prošetřujeme využití vlastních vazeb na platformě Xamarin. Pokud chcete informovat budoucí úsilí o rozvoj, využijte tento průzkum .
Xamarin umožňuje vývojářům mobilních aplikací vytvářet mobilní aplikace nativní pro různé platformy pomocí sady Visual Studio a jazyka C#. Komponenty sady Sdk platformy Android můžete používat předem, ale v mnoha případech také chcete používat sady SDK třetích stran napsané pro danou platformu a Xamarin to umožňuje provádět prostřednictvím vazeb. Aby bylo možné do aplikace Xamarin.Android začlenit architekturu androidu třetí strany, musíte pro ni vytvořit vazbu Xamarin.Android, abyste ji mohli použít ve svých aplikacích.
Platforma Android spolu s nativními jazyky a nástroji se neustále vyvíjí, včetně nedávného zavedení jazyka Kotlin, který se nakonec nastaví na nahrazení Javy. Existuje řada 3d party SAD SDK, které už byly migrovány z Javy do Kotlinu a představují nové výzvy. I když je proces vazby Kotlin podobný Javě, vyžaduje další kroky a nastavení konfigurace k úspěšnému sestavení a spuštění v rámci aplikace Xamarin.Android.
Cílem tohoto dokumentu je nastínit obecný přístup k řešení tohoto scénáře a poskytnout podrobný průvodce jednoduchým příkladem.
Pozadí
Kotlin byl vydán v únoru 2016 a byl umístěn jako alternativa ke standardnímu kompilátoru Java do Android Studia do roku 2017. Později v roce 2019 google oznámil, že programovací jazyk Kotlin se stal upřednostňovaným jazykem pro vývojáře aplikací pro Android. Přístup k vazbám vysoké úrovně se podobá procesu vazby běžných knihoven Java s několika důležitými kroky specifickými pro Kotlin.
Požadavky
K dokončení tohoto návodu budete potřebovat:
Vytvoření nativní knihovny
Prvním krokem je vytvoření nativní knihovny Kotlin pomocí Android Studia. Knihovnu obvykle poskytuje vývojář třetí strany nebo je k dispozici v úložišti Maven společnosti Google a dalších vzdálených úložištích. Například v tomto kurzu se vytvoří vazba pro knihovnu Kotlin pro výběr bublin:
Stáhněte zdrojový kód z GitHubu pro knihovnu a rozbalte ho do místní složky Bubble-Picker.
Spusťte Android Studio a vyberte Možnost Otevřít existující nabídku projektu Android Studio a zvolte místní složku Pro výběr bublin:
Ověřte, že je Android Studio aktuální, včetně Gradle. Zdrojový kód lze úspěšně sestavit na Android Studiu verze 3.5.3, Gradle v5.4.1. Pokyny k aktualizaci Gradle na nejnovější verzi Gradle najdete tady.
Ověřte, že je nainstalovaná požadovaná sada Android SDK. Zdrojový kód vyžaduje Sadu Android SDK v25. Otevřete možnost nabídky Správce sady Sdk Nástroje > pro instalaci komponent sady SDK.
Aktualizujte a synchronizujte hlavní konfigurační soubor build.gradle umístěný v kořenové složce projektu:
Nastavení verze Kotlin na 1.3.10
buildscript { ext.kotlin_version = '1.3.10' }
Zaregistrujte výchozí úložiště Maven společnosti Google, aby bylo možné vyřešit závislost knihovny podpory:
allprojects { repositories { jcenter() maven { url "https://maven.google.com" } } }
Jakmile se konfigurační soubor aktualizuje, je mimo synchronizaci a Gradle zobrazí tlačítko Synchronizovat, stiskněte ho a počkejte na dokončení procesu synchronizace:
Tip
Mezipaměť závislostí Gradle může být poškozená, někdy k tomu dochází po vypršení časového limitu síťového připojení. Znovu stáhněte závislosti a synchronizační projekt (vyžaduje síť).
Tip
Stav procesu sestavení Gradle (démon) může být poškozený. Tento problém může vyřešit zastavení všech démon Gradle. Zastavení procesů sestavení Gradle (vyžaduje restartování). V případě poškozenýchprocesůch
Tip
Váš projekt může používat modul plug-in třetí strany, který není kompatibilní s ostatními moduly plug-in v projektu nebo verzí Gradle požadované projektem.
Otevřete nabídku Gradle na pravé straně, přejděte do nabídky úkoly bubblepickeru>, spusťte úlohu sestavení tak, že na ni poklepete a počkáte na dokončení procesu sestavení:
Otevřete prohlížeč souborů kořenové složky a přejděte do složky sestavení: Bubble-Picker -> bubblepicker - build ->> outputs -> aar, uložte soubor bubblepicker-release.aar jako bubblepicker-v1.0.aar, tento soubor se použije později v procesu vazby:
Soubor AAR je archiv pro Android, který obsahuje zkompilovaný zdrojový kód a prostředky Kotlin, které Android vyžaduje ke spuštění aplikace pomocí této sady SDK.
Příprava metadat
Druhým krokem je příprava souboru transformace metadat, který používá Xamarin.Android ke generování příslušných tříd jazyka C#. Projekt vazby Xamarin.Android vyhledá všechny nativní třídy a členy z daného archivu Androidu a následně vygeneruje soubor XML s příslušnými metadaty. Ručně vytvořený soubor transformace metadat se pak použije na dříve vygenerovaný směrný plán a vytvoří konečný definiční soubor XML použitý k vygenerování kódu jazyka C#.
Metadata používají syntaxi XPath a používá ho Generátor vazeb k ovlivnění vytváření sestavení vazby. Další informace o transformacích, které je možné použít, najdete v článku o metadatech vazby Java:
Vytvořte prázdný soubor Metadata.xml :
<?xml version="1.0" encoding="UTF-8"?> <metadata> </metadata>
Definování transformací XML:
Nativní knihovna Kotlin má dvě závislosti, které nechcete vystavit světu jazyka C#, definují dvě transformace, které je úplně ignorují. Důležité je říci, že nativní členy nebudou odstraněny z výsledného binárního souboru, nebudou generovány pouze třídy jazyka C#. Dekompiler Jazyka Java lze použít k identifikaci závislostí. Spusťte nástroj a otevřete soubor AAR vytvořený dříve, proto se zobrazí struktura archivu Androidu, která bude odrážet všechny závislosti, hodnoty, prostředky, manifest a třídy:
Transformace pro přeskočení zpracování těchto balíčků jsou definovány pomocí pokynů XPath:
<remove-node path="/api/package[starts-with(@name,'org.jbox2d')]" /> <remove-node path="/api/package[starts-with(@name,'org.slf4j')]" />
Nativní
BubblePicker
třída má dvě metodygetBackgroundColor
asetBackgroundColor
následující transformace ji změní na vlastnost jazyka C#BackgroundColor
:<attr path="/api/package[@name='com.igalata.bubblepicker.rendering']/class[@name='BubblePicker']/method[@name='getBackground' and count(parameter)=0]" name="propertyName">BackgroundColor</attr> <attr path="/api/package[@name='com.igalata.bubblepicker.rendering']/class[@name='BubblePicker']/method[@name='setBackground' and count(parameter)=1 and parameter[1][@type='int']]" name="propertyName">BackgroundColor</attr>
Nepodepsané typy
UInt, UShort, ULong, UByte
vyžadují zvláštní zpracování. U těchto typů Kotlin změní názvy metod a typy parametrů automaticky, což se projeví ve vygenerovaném kódu:public open fun fooUIntMethod(value: UInt) : String { return "fooUIntMethod${value}" }
Tento kód je zkompilován do následujícího bajtového kódu Javy:
@NotNull public String fooUIntMethod-WZ4Q5Ns(int value) { return "fooUIntMethod" + UInt.toString-impl(value); }
Kromě toho, související typy, jako
UIntArray, UShortArray, ULongArray, UByteArray
jsou také ovlivněny Kotlin. Název metody se změní tak, aby zahrnoval další příponu a parametry se změní na pole prvků podepsaných verzí stejných typů. V příkladu pod parametrem typuUIntArray
se automaticky převede naint[]
a název metody se změní zfooUIntArrayMethod
nafooUIntArrayMethod--ajY-9A
. Druhá je zjištěna nástroji Xamarin.Android a vygenerována jako platný název metody:public open fun fooUIntArrayMethod(value: UIntArray) : String { return "fooUIntArrayMethod${value.size}" }
Tento kód je zkompilován do následujícího bajtového kódu Javy:
@NotNull public String fooUIntArrayMethod--ajY-9A(@NotNull int[] value) { Intrinsics.checkParameterIsNotNull(value, "value"); return "fooUIntArrayMethod" + UIntArray.getSize-impl(value); }
Aby bylo možné ho pojmenovat smysluplně, můžete do Metadata.xml přidat následující metadata, která aktualizují název zpět tak, aby byl původně definovaný v kódu Kotlin:
<attr path="/api/package[@name='com.microsoft.simplekotlinlib']/class[@name='FooClass']/method[@name='fooUIntArrayMethod--ajY-9A']" name="managedName">fooUIntArrayMethod</attr>
V ukázce BubblePickeru nejsou žádní členové používající nepodepsané typy, takže nejsou potřeba žádné další změny.
Členy Kotlinu s obecnými parametry se ve výchozím nastavení transformují na parametry Javy.
Lang.Object
Typ. Například metoda Kotlin má obecný parametr <T>:public open fun <T>fooGenericMethod(value: T) : String { return "fooGenericMethod${value}" }
Po vygenerování vazby Xamarin.Android se metoda zobrazí v jazyce C# následujícím způsobem:
[Register ("fooGenericMethod", "(Ljava/lang/Object;)Ljava/lang/String;", "GetFooGenericMethod_Ljava_lang_Object_Handler")] [JavaTypeParameters (new string[] { "T" })] public virtual string FooGenericMethod (Java.Lang.Object value);
Vazby Xamarin.Android nepodporují obecné typy Java a Kotlin, takže se vytvoří zobecněná metoda jazyka C#pro přístup k obecnému rozhraní API. Jako alternativní řešení můžete vytvořit obálkovou knihovnu Kotlin a vystavit požadovaná rozhraní API silným typem bez obecných typů. Případně můžete vytvořit pomocné rutiny na straně jazyka C#, které budou problém řešit stejným způsobem prostřednictvím rozhraní API se silnými typy.
Tip
Při transformaci metadat se na vygenerovanou vazbu dají použít všechny změny. Článek o vazbě knihovny Java vysvětluje podrobnosti o tom, jak se metadata generují a zpracovávají.
Vytvoření knihovny vazeb
Dalším krokem je vytvoření projektu vazby Xamarin.Android pomocí šablony vazby sady Visual Studio, přidání požadovaných metadat, nativních odkazů a následné sestavení projektu pro vytvoření spotřební knihovny:
Otevřete Visual Studio pro Mac a vytvořte nový projekt knihovny vazeb Xamarin.Android, pojmenujte ho v tomto případě testBubblePicker.Binding a dokončete průvodce. Šablona vazby Xamarin.Android se nachází v následující cestě: Knihovna vazeb knihovny > Androidu>:
Ve složce Transformace existují tři hlavní transformační soubory:
- Metadata.xml – Umožňuje provádět změny v konečném rozhraní API, například změnit obor názvů vygenerované vazby.
- EnumFields.xml – obsahuje mapování mezi int konstantami Jazyka Java a výčty jazyka C#.
- EnumMethods.xml – Umožňuje změnit parametry metody a vracet typy z int konstant Jazyka Java do výčtů jazyka C#.
Vyprázdněte soubory EnumFields.xml a EnumMethods.xml a aktualizujte Metadata.xml , aby se definovaly transformace.
Nahraďte existující soubor Transformací/Metadata.xml souborem Metadata.xml vytvořeným v předchozím kroku. V okně vlastností ověřte, že je akce sestavení souboru nastavená na TransformationFile:
Přidejte soubor bubblepicker-v1.0.aar , který jste vytvořili v kroku 1, do projektu vazby jako nativní odkaz. Pokud chcete přidat odkazy na nativní knihovnu, otevřete finder a přejděte do složky s archivem Androidu. Přetáhněte archiv do složky Jars v Průzkumník řešení. Alternativně můžete použít možnost Přidat místní nabídku ve složce Jars a zvolit Existující soubory.... Zvolte, že chcete soubor zkopírovat do adresáře pro účely tohoto názorného postupu. Nezapomeňte ověřit, že je akce sestavení nastavená na LibraryProjectZip:
Přidejte odkaz na balíček NuGet Xamarin.Kotlin.StdLib. Tento balíček je vazbou pro standardní knihovnu Kotlin. Bez tohoto balíčku bude vazba fungovat pouze v případě, že knihovna Kotlin nepoužívá žádné konkrétní typy Kotlin, jinak všichni tito členové nebudou vystaveni jazyku C# a žádná aplikace, která se pokusí tuto vazbu využívat, dojde k chybě za běhu.
Tip
Z důvodu omezení Xamarin.Android je možné pro každý projekt vazby přidat nástroje pro vazby pouze jeden archiv Androidu (AAR). Pokud je potřeba zahrnout více souborů AAR, vyžaduje se více projektů Xamarin.Android, jeden pro každou AAR. Pokud by se jednalo o tento názorný postup, předchozí čtyři akce tohoto kroku by se musely opakovat pro každý archiv. Jako alternativní možnost je možné ručně sloučit více archivů Androidu jako jeden archiv a v důsledku toho můžete použít jeden projekt vazby Xamarin.Android.
Poslední akcí je sestavení knihovny a provedení žádné chyby kompilace. V případě chyb kompilace je možné je vyřešit a zpracovat pomocí souboru Metadata.xml, který jste vytvořili dříve přidáním metadat transformace XML, která přidají, odeberou nebo přejmenují členy knihovny.
Využití knihovny vazeb
Posledním krokem je využití knihovny vazeb Xamarin.Android v aplikaci Xamarin.Android. Vytvořte nový projekt Xamarin.Android, přidejte odkaz na knihovnu vazeb a vykreslujte uživatelské rozhraní pro výběr bublin:
Vytvořte projekt Xamarin.Android. Jako výchozí bod použijte aplikaci pro Android App> pro Android > a vyberte možnost Nejnovější a Nejlepší jako cílové platformy, abyste se vyhnuli problémům s kompatibilitou. Tento projekt cílí na všechny následující kroky:
Přidejte odkaz na projekt vazby nebo přidejte odkaz na knihovnu DLL vytvořenou dříve:
Přidejte odkaz na balíček NuGet Xamarin.Kotlin.StdLib, který jste přidali do projektu vazby Xamarin.Android dříve. Přidává podporu pro všechny konkrétní typy Kotlin, které potřebují předat modul runtime. Bez tohoto balíčku je možné aplikaci zkompilovat, ale dojde k chybě za běhu:
BubblePicker
Přidejte ovládací prvek do rozložení androidu proMainActivity
. Otevřete soubor testBubblePicker/Resources/layout/content_main.xml a připojte řídicí uzel BubblePicker jako poslední prvek kořenového ovládacího prvku RelativeLayout:<?xml version="1.0" encoding="utf-8"?> <RelativeLayout …> … <com.igalata.bubblepicker.rendering.BubblePicker android:id="@+id/picker" android:layout_width="match_parent" android:layout_height="match_parent" app:backgroundColor="@android:color/white" /> </RelativeLayout>
Aktualizujte zdrojový kód aplikace a přidejte logiku inicializace do
MainActivity
sady SDK pro výběr bublin:protected override void OnCreate(Bundle savedInstanceState) { ... var picker = FindViewById<BubblePicker>(Resource.Id.picker); picker.BubbleSize = 20; picker.Adapter = new BubblePickerAdapter(); picker.Listener = new BubblePickerListener(picker); ... }
BubblePickerAdapter
aBubblePickerListener
jsou dvě třídy, které se mají vytvořit od nuly, které zpracovávají data bublin a interakci s ovládacími prvky:public class BubblePickerAdapter : Java.Lang.Object, IBubblePickerAdapter { private List<string> _bubbles = new List<string>(); public int TotalCount => _bubbles.Count; public BubblePickerAdapter() { for (int i = 0; i < 10; i++) { _bubbles.Add($"Item {i}"); } } public PickerItem GetItem(int itemIndex) { if (itemIndex < 0 || itemIndex >= _bubbles.Count) return null; var result = _bubbles[itemIndex]; var item = new PickerItem(result); return item; } } public class BubblePickerListener : Java.Lang.Object, IBubblePickerListener { public View Picker { get; } public BubblePickerListener(View picker) { Picker = picker; } public void OnBubbleDeselected(PickerItem item) { Snackbar.Make(Picker, $"Deselected: {item.Title}", Snackbar.LengthLong) .SetAction("Action", (Android.Views.View.IOnClickListener)null) .Show(); } public void OnBubbleSelected(PickerItem item) { Snackbar.Make(Picker, $"Selected: {item.Title}", Snackbar.LengthLong) .SetAction("Action", (Android.Views.View.IOnClickListener)null) .Show(); } }
Spusťte aplikaci, která by měla vykreslit uživatelské rozhraní pro výběr bublin:
Ukázka vyžaduje další kód pro vykreslení stylu prvků a zpracování interakcí, ale
BubblePicker
ovládací prvek byl úspěšně vytvořen a aktivován.
Gratulujeme! Úspěšně jste vytvořili aplikaci Xamarin.Android a knihovnu vazeb, která využívá knihovnu Kotlin.
Teď byste měli mít základní aplikaci Xamarin.Android, která používá nativní knihovnu Kotlin prostřednictvím knihovny vazeb Xamarin.Android. Tento názorný postup záměrně používá základní příklad k lepšímu zdůraznění klíčových konceptů, které se zavádějí. V reálných scénářích budete pravděpodobně muset zveřejnit větší počet rozhraní API a použít na ně transformace metadat.