Binda Java-bibliotek

Ekosystemet av tredjepartsbibliotek för Android är omfattande. På grund av detta är det ofta klokt att använda ett befintligt Android-bibliotek än att skapa ett nytt.

Med .NET för Android kan du göra detta med ett bindningsbibliotek som automatiskt omsluter biblioteket med C#-omslutningar så att du kan anropa Java-kod via C#-anrop.

Detta implementeras med hjälp av Managed Callable Wrappers (MCW). MCW är en JNI-brygga som används när hanterad kod behöver anropa Java-kod. Hanterade anropsbara omslutningar ger också stöd för underklassning av Java-typer och för att åsidosätta virtuella metoder på Java-typer. På samma sätt, när Android Runtime-kod (ART) vill anropa hanterad kod, gör den det via en annan JNI-brygga som kallas Android Callable Wrappers (ACW). Den här arkitekturen illustreras i följande diagram:

Arkitektur för Android JNI-brygga

Ett bindningsbibliotek är ett bibliotek som innehåller hanterade anropbara omslutare för Java-typer. Här är till exempel en Java-typ, MyClass, som vi vill omsluta i ett bindningsbibliotek:

package com.contoso.mycode;

public class MyClass
{
    public String myMethod (int i) { ... }
}

När vi har genererat ett bindningsbibliotek för .jar som innehåller MyClasskan vi instansiera det och anropa metoder på det från C#:

var instance = new MyClass ();

string result = instance.MyMethod (42);

Om du vill skapa det här bindningsbiblioteket använder du mallen .NET för Android Java-bindningsbibliotek . Det resulterande bindningsprojektet skapar en .NET-sammansättning med MCW-klasserna, .jar.aar-filer och resurser för Android-biblioteksprojekt som är inbäddade i den. Genom att referera till den resulterande bindningsbibliotekssammansättningen kan du återanvända ett befintligt Java-bibliotek i ditt .NET för Android-projekt.

När du refererar till typer i bindningsbiblioteket måste du använda namnområdet för bindningsbiblioteket. Vanligtvis lägger du till ett using direktiv överst i C#-källfilerna som är .NET-namnområdesversionen av Java-paketnamnet. Om Java-paketnamnet för din bundna .jar till exempel är följande:

com.contoso.package

Sedan skulle du placera följande using -instruktion överst i C#-källfilerna för att komma åt typer i den bundna .jar-filen :

using Com.Contoso.Package;

När du binder ett befintligt Android-bibliotek måste du tänka på följande:

  • Finns det några externa beroenden för biblioteket? – Alla Java-beroenden som krävs av Android-biblioteket måste ingå i .NET för Android-projektet via ett NuGet-paket eller som en AndroidLibrary. Alla inbyggda sammansättningar måste läggas till i bindningsprojektet som en AndroidNativeLibrary.

  • Vilken version av Android-API:et har Android-biblioteket som mål? – Det går inte att "nedgradera" Android API-nivån. se till att .NET for Android-bindningsprojektet har samma API-nivå (eller högre) som Android-biblioteket.

Anpassa Java-API:er till C⧣

.NET för Android-bindningsgeneratorn ändrar vissa Java-idiom och mönster så att de motsvarar .NET-mönster. I följande lista beskrivs hur Java mappas till C#/.NET:

  • Setter/Getter-metoder i Java är Egenskaper i .NET.

  • Fält i Java är Egenskaper i .NET.

  • Lyssnare/lyssnargränssnitt i Java är händelser i .NET. Parametrarna för metoderna i motringningsgränssnitten representeras av en EventArgs underklass.

  • En statisk kapslad klass i Java är en kapslad klass i .NET.

  • En inre klass i Java är en kapslad klass med en instanskonstruktor i C#.

Inkludera ett inbyggt bibliotek i en bindning

Det kan vara nödvändigt att inkludera ett .so-bibliotek i ett .NET för Android-bindningsprojekt som en del av bindningen av ett Java-bibliotek. När den omslutna Java-koden körs misslyckas .NET för Android med att göra JNI-anropet och felmeddelandet java.lang.UnsatisfiedLinkError: Den interna metoden hittades inte: visas i logcat-ut för programmet.

Korrigeringen för detta är att manuellt läsa in .so-biblioteket med ett anrop till Java.Lang.JavaSystem.LoadLibrary. Om du till exempel antar att ett .NET för Android-projekt har delat bibliotek libpocketsphinx_jni.so som ingår i bindningsprojektet med en byggåtgärd av AndroidNativeLibrary, läser följande kodfragment (körs innan du använder det delade biblioteket) in .so-biblioteket :

Java.Lang.JavaSystem.LoadLibrary("pocketsphinx_jni");

Bindningsscenarier

Följande bindningsscenarioguider kan hjälpa dig att binda ett Java-bibliotek (eller -bibliotek) för inkorporering till din app:

  • Bindning av ett Java-bibliotek är en genomgång för att skapa bindningsbibliotek för lokalt tillgängliga .jar.aar-filer/.

  • Att binda ett Java-bibliotek från Maven är en genomgång för att skapa bindningsbibliotek för .jar.aar-filer/ som finns på en Maven-lagringsplats.

  • Anpassning av bindningar förklarar hur du gör manuella ändringar av bindningen för att lösa byggfel och forma det resulterande API:et så att det blir mer "C#-liknande".

  • Felsökningsbindningar visar vanliga scenarier för bindningsfel, förklarar möjliga orsaker och ger förslag på hur du kan lösa dessa fel.