Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Vytvoření vazby knihovny pro Android (soubor .aar nebo .jar) je zřídka jednoduchou záležitostí; obvykle vyžaduje další úsilí ke zmírnění problémů, které vyplývají z rozdílů mezi Javou a .NET. Tyto problémy zabrání rozhraní .NET pro Android v připojení ke knihovně pro Android a zobrazí se jako chybová hlášení v protokolu sestavení. Tato příručka obsahuje několik tipů pro řešení potíží, seznam některých nejběžnějších problémů a scénářů a poskytuje možná řešení úspěšného propojení knihovny pro Android.
Při připojování existující knihovny pro Android je nutné mít na paměti následující body:
Externí závislosti pro knihovnu – Všechny závislosti Javy vyžadované knihovnou Androidu musí být součástí projektu .NET pro Android prostřednictvím balíčku NuGet nebo jako AndroidLibrary.
Úroveň rozhraní Android API, na kterou cílí knihovna Androidu , není možné downgradovat úroveň rozhraní ANDROID API; ujistěte se, že projekt vazby .NET pro Android cílí na stejnou úroveň rozhraní API (nebo vyšší) jako knihovna Androidu.
Návod
Wiki repozitáře Binding Tooling na GitHubu je skvělým prostředkem a obsahuje další informace o řešení potíží, které můžou pomoct s konkrétními případy.
Prvním krokem při řešení potíží s vazbou knihovny .NET pro Android je povolení diagnostického výstupu MSBuild. Po povolení výstupu diagnostiky znovu sestavte projekt vazby .NET pro Android a prozkoumejte protokol sestavení a vyhledejte povědomí o příčině problému.
Může také být užitečné dekompilovat knihovnu Androidu a prozkoumat typy a metody, které se .NET pro Android snaží svázat. Podrobnější informace najdete dále v této příručce.
Dekompilování knihovny pro Android
Zjišťování tříd a metod třídy v Javě může poskytovat cenné informace, které vám pomohou s propojením knihovny. JD-GUI je grafický nástroj, který může zobrazit zdrojový kód Java ze souborů CLASS obsažených v SOUBORU JAR.
Chcete-li dekompilovat knihovnu pro Android, otevřete soubor . Soubor JAR s dekompilerem Java Pokud je knihovna souborem .AAR, bude zdrojový kód Java ve složce classes.jar archivu. Následuje ukázkový snímek obrazovky s použitím JD-GUI k analýze Picassa JAR:
Jakmile dekompilujete knihovnu androidu, prozkoumejte zdrojový kód. Obecně řečeno, hledejte:
Třídy, které mají charakteristiky obfuskace – charakteristiky obfuskovaných tříd zahrnují:
- Název třídy obsahuje , $tj. a$.class.
- Název třídy je zcela složen z malých písmen, tj. a.class.
importpříkazy pro neodkazované knihovny – Identifikujte nerozpoznanou knihovnu a přidejte tyto závislosti do projektu vazby .NET pro Android s příslušnou vazbou z NuGetu nebo pomocí akce sestaveníAndroidLibrary.
Poznámka:
Dekompilování knihovny Java může být zakázáno nebo podléhat právním omezením na základě místních zákonů nebo licence, pod kterou byla knihovna Java publikována. V případě potřeby zapojte služby právního odborníka, než se pokusíte dekompilovat knihovnu Java a prozkoumat zdrojový kód.
Prohlédnout api.xml
V rámci vytváření projektu vazby vygeneruje .NET pro Android název souboru XML obj/Debug/api.xml:
Tento soubor obsahuje seznam všech rozhraní Java API, která se .NET pro Android snaží navázat. Obsah tohoto souboru může pomoct identifikovat všechny chybějící typy nebo metody, duplicitní vazbu. I když kontrola tohoto souboru je zdlouhavá a časově náročná, může poskytnout vodítka k tomu, co může způsobovat jakékoli problémy s vazbou. Například api.xml může odhalit, že vlastnost vrací nevhodný typ nebo že existují dva typy, které sdílejí stejný spravovaný název.
Známé problémy
Tato část obsahuje seznam některých běžných chybových zpráv nebo příznaků, ke kterým dochází při pokusu o vytvoření vazby knihovny androidu.
Problém: Chybějící typy jazyka C# ve vygenerovaném výstupu
Vazba .dll se sestaví, ale chybí některé typy Javy, nebo vygenerovaný zdrojový kód v C# se nevytvoří kvůli chybě, která uvádí, že chybí typy.
Možné příčiny:
K této chybě může dojít z několika důvodů, jak je uvedeno níže:
Vázaná knihovna může odkazovat na druhou knihovnu Java. Pokud veřejné rozhraní API pro vázanou knihovnu používá typy z druhé knihovny, musíte odkazovat také na spravovanou vazbu pro druhou knihovnu.
Java umožňuje odvození veřejné třídy z neveřejné třídy, ale to není podporováno v .NET. Vzhledem k tomu, že generátor vazeb negeneruje vazby pro neveřejné třídy, odvozené třídy, jako jsou tyto, nelze správně vygenerovat. Chcete-li tento problém vyřešit, buď odeberte položku metadat pro tyto odvozené třídy pomocí remove-node v Metadata.xml, nebo opravte metadata, která činí neveřejnou třídu veřejné. I když druhé řešení vytvoří vazbu tak, aby se zdroj jazyka C# sestavil, neměla by se použít neverejná třída.
Například:
<attr path="/api/package[@name='com.some.package']/class[@name='SomeClass']" name="visibility">public</attr>Nástroje, které zatemňují knihovny Java, mohou kolidovat s .NET for Android Binding Generatorem a jeho schopností generovat obálkové třídy v jazyce C#. Následující fragment kódu ukazuje, jak aktualizovat Metadata.xml a zrušit tak název třídy:
<attr path="/api/package[@name='{package_name}']/class[@name='{name}']" name="obfuscated">false</attr>
Problém: Vygenerovaný zdroj jazyka C# se nevytvořuje kvůli neshodě typu parametru
Vygenerovaný zdroj jazyka C# se nezkompiluje. Typy parametrů přepisované metody se neshodují.
Možné příčiny:
.NET pro Android obsahuje řadu polí Java, která jsou namapovaná na výčty v vazbách jazyka C#. To může způsobit nekompatibilitu typu ve vygenerovaných vazbách. Pokud chcete tento problém vyřešit, musí být podpisy metody vytvořené z generátoru vazeb upraveny tak, aby používaly výčty. Další informace naleznete v tématu Vytváření výčtů.
Problém: Duplicitní uživatelské typy EventArgs
Sestavení selže kvůli duplicitním vlastním typům EventArgs. K této chybě dochází:
error CS0102: The type `Com.Google.Ads.Mediation.DismissScreenEventArgs' already contains a definition for `p0'
Možné příčiny:
Důvodem je, že mezi typy událostí, které pocházejí z více než jednoho typu rozhraní „posluchač“, existuje konflikt sdílejícího metody s identickými názvy. Pokud jsou například dvě rozhraní Java, jak je vidět v následujícím příkladu, generátor vytvoří DismissScreenEventArgs pro obojí MediationBannerListener a MediationInterstitialListener, což vede k chybě.
// Java:
public interface MediationBannerListener {
void onDismissScreen(MediationBannerAdapter p0);
}
public interface MediationInterstitialListener {
void onDismissScreen(MediationInterstitialAdapter p0);
}
Je to navrženo tak, aby se vyhnulo zdlouhavým názvům typů argumentů událostí. Aby se zabránilo těmto konfliktům, vyžaduje se určitá transformace metadat. Editujte Transforms\Metadata.xml a přidejte argsType atribut na jedno z rozhraní (nebo na metodu rozhraní):
<attr path="/api/package[@name='com.google.ads.mediation']/
interface[@name='MediationBannerListener']/method[@name='onDismissScreen']"
name="argsType">BannerDismissScreenEventArgs</attr>
<attr path="/api/package[@name='com.google.ads.mediation']/
interface[@name='MediationInterstitialListener']/method[@name='onDismissScreen']"
name="argsType">IntersitionalDismissScreenEventArgs</attr>
<attr path="/api/package[@name='android.content']/
interface[@name='DialogInterface.OnClickListener']"
name="argsType">DialogClickEventArgs</attr>
Problém: Třída neimplementuje metodu rozhraní
Vytvoří se chybová zpráva, která indikuje, že vygenerovaná třída neimplementuje metodu, která je vyžadována pro rozhraní, které vygenerovaná třída implementuje. Když se ale podíváte na vygenerovaný kód, uvidíte, že je metoda implementovaná.
Tady je příklad chyby:
obj\Debug\generated\src\Oauth.Signpost.Basic.HttpURLConnectionRequestAdapter.cs(8,23):
error CS0738: 'Oauth.Signpost.Basic.HttpURLConnectionRequestAdapter' does not
implement interface member 'Oauth.Signpost.Http.IHttpRequest.Unwrap()'.
'Oauth.Signpost.Basic.HttpURLConnectionRequestAdapter.Unwrap()' cannot implement
'Oauth.Signpost.Http.IHttpRequest.Unwrap()' because it does not have the matching
return type of 'Java.Lang.Object'
Možné příčiny:
Jedná se o problém, ke kterému dochází u vazeb metod Java s kovariantním návratovým typem. V tomto příkladu musí metoda Oauth.Signpost.Http.IHttpRequest.UnWrap() vrátit Java.Lang.Object. Metoda Oauth.Signpost.Basic.HttpURLConnectionRequestAdapter.UnWrap() však má návratový HttpURLConnectiontyp . Tento problém můžete vyřešit dvěma způsoby:
Přidejte deklaraci částečné třídy pro
HttpURLConnectionRequestAdaptera explicitně implementujteIHttpRequest.Unwrap():namespace Oauth.Signpost.Basic { partial class HttpURLConnectionRequestAdapter { Java.Lang.Object OauthSignpost.Http.IHttpRequest.Unwrap() { return Unwrap(); } } }Odeberte kovarianci z vygenerovaného kódu v jazyce C#. To zahrnuje přidání následující transformace do transformací\Metadata.xml což způsobí, že vygenerovaný kód jazyka C# bude mít návratový
Java.Lang.Objecttyp:<attr path="/api/package[@name='oauth.signpost.basic']/class[@name='HttpURLConnectionRequestAdapter']/method[@name='unwrap']" name="managedReturn">Java.Lang.Object </attr>
Problém: Kolize názvů ve vnitřních třídách / vlastnostech
Konflikt ve viditelnosti zděděných objektů
V Javě není nutné, aby odvozená třída měla stejnou viditelnost jako nadřazená třída. Java to vyřeší za vás. V jazyce C# musí být explicitní, takže musíte zajistit, aby všechny třídy v hierarchii měly odpovídající viditelnost. Následující příklad ukazuje, jak změnit název balíčku Java z com.evernote.android.job na Evernote.AndroidJob:
<!-- Change the visibility of a class -->
<attr path="/api/package[@name='namespace']/class[@name='ClassName']" name="visibility">public</attr>
<!-- Change the visibility of a method -->
<attr path="/api/package[@name='namespace']/class[@name='ClassName']/method[@name='MethodName']" name="visibility">public</attr>
Problém: Knihovna .so požadovaná vazbou se nenačítá
Některé projekty vazeb můžou záviset také na funkcích v knihovně .so . Je možné, že .NET pro Android automaticky nenačte knihovnu .so . Při spuštění zabaleného Java kódu se .NET pro Android nepodaří provést volání JNI a chybová zpráva java.lang.UnsatisfiedLinkError: Nativní metoda nebyla nalezena: se zobrazí ve výstupu logcat pro aplikaci.
Oprava tohoto problému spočívá v ručním načtení knihovny .so s voláním Java.Lang.JavaSystem.LoadLibrary. Předpokládejme například, že projekt .NET pro Android má sdílenou knihovnu libpocketsphinx_jni.so součástí projektu vazby s akcí sestavení EmbeddedNativeLibrary, následující fragment kódu (spuštěn před použitím sdílené knihovny) načte knihovnu .so :
Java.Lang.JavaSystem.LoadLibrary("pocketsphinx_jni");